Cataclysm BN
map Class Reference

Manage and cache data about a part of the map. More...

#include <map.h>

Inheritance diagram for map:
tinymap fake_map

Classes

struct  apparent_light_info
 

Public Member Functions

 map (int mapsize=MAPSIZE, bool zlev=false)
 
 map (bool zlev)
 
virtual ~map ()
 
mapoperator= (const map &)=delete
 
mapoperator= (map &&)
 
void set_transparency_cache_dirty (const int zlev)
 Sets a dirty flag on the a given cache. More...
 
void set_transparency_cache_dirty (const tripoint &p)
 
void set_seen_cache_dirty (const tripoint change_location)
 
void set_seen_cache_dirty (const int zlevel)
 
void set_outside_cache_dirty (const int zlev)
 
void set_floor_cache_dirty (const int zlev)
 
void set_suspension_cache_dirty (const int zlev)
 
void set_pathfinding_cache_dirty (int zlev)
 
void set_memory_seen_cache_dirty (const tripoint &p)
 
void invalidate_map_cache (const int zlev)
 
bool check_seen_cache (const tripoint &p) const
 
bool check_and_set_seen_cache (const tripoint &p) const
 
void on_vehicle_moved (int smz)
 Callback invoked when a vehicle has moved. More...
 
lit_level apparent_light_at (const tripoint &p, const visibility_variables &cache) const
 Determine the visible light level for a tile, based on light_at for the tile, vision distance, etc. More...
 
visibility_type get_visibility (lit_level ll, const visibility_variables &cache) const
 
std::tuple< maptile, maptile, maptileget_wind_blockers (const int &winddirection, const tripoint &pos)
 
void draw (const catacurses::window &w, const tripoint &center)
 Draw a visible part of the map into w. More...
 
void drawsq (const catacurses::window &w, const tripoint &p, const drawsq_params &params) const
 Draw the map tile at the given coordinate. More...
 
void save ()
 Add currently loaded submaps (in grid) to the mapbuffer. More...
 
void load (const tripoint &w, bool update_vehicles)
 Load submaps into grid. More...
 
void load (const tripoint_abs_sm &w, bool update_vehicles)
 
void shift (const point &s)
 Shift the map along the vector s. More...
 
void vertical_shift (int newz)
 Moves the map vertically to (not by!) newz. More...
 
void clear_spawns ()
 
void clear_traps ()
 
maptile maptile_at (const tripoint &p) const
 
maptile maptile_at (const tripoint &p)
 
int move_cost (const tripoint &p, const vehicle *ignored_vehicle=nullptr) const
 Calculate the cost to move past the tile at p. More...
 
int move_cost (const point &p, const vehicle *ignored_vehicle=nullptr) const
 
bool impassable (const tripoint &p) const
 
bool impassable (const point &p) const
 
bool passable (const tripoint &p) const
 
bool passable (const point &p) const
 
bool is_wall_adjacent (const tripoint &center) const
 
int move_cost_ter_furn (const tripoint &p) const
 Similar behavior to move_cost(), but ignores vehicles. More...
 
int move_cost_ter_furn (const point &p) const
 
bool impassable_ter_furn (const tripoint &p) const
 
bool passable_ter_furn (const tripoint &p) const
 
int combined_movecost (const tripoint &from, const tripoint &to, const vehicle *ignored_vehicle=nullptr, int modifier=0, bool flying=false, bool via_ramp=false) const
 Cost to move out of one tile and into the next. More...
 
bool valid_move (const tripoint &from, const tripoint &to, bool bash=false, bool flying=false, bool via_ramp=false) const
 Returns true if a creature could walk from from to to in one step. More...
 
double ranged_target_size (const tripoint &p) const
 Size of map objects at p for purposes of ranged combat. More...
 
bool sees (const tripoint &F, const tripoint &T, int range) const
 Returns whether F sees T with a view range of range. More...
 
int obstacle_coverage (const tripoint &loc1, const tripoint &loc2) const
 Returns coverage of target in relation to the observer. More...
 
int coverage (const tripoint &p) const
 Returns coverage value of the tile. More...
 
bool clear_path (const tripoint &f, const tripoint &t, int range, int cost_min, int cost_max) const
 Check whether there's a direct line of sight between F and T with the additional movecost restraints. More...
 
void reachable_flood_steps (std::vector< tripoint > &reachable_pts, const tripoint &f, int range, int cost_min, int cost_max) const
 Populates a vector of points that are reachable within a number of steps from a point. More...
 
std::vector< tripointfind_clear_path (const tripoint &source, const tripoint &destination) const
 Iteratively tries Bresenham lines with different biases until it finds a clear line or decides there isn't one. More...
 
bool accessible_items (const tripoint &t) const
 Check whether the player can access the items located . More...
 
std::vector< tripointget_dir_circle (const tripoint &f, const tripoint &t) const
 Calculate next search points surrounding the current position. More...
 
std::vector< tripointroute (const tripoint &f, const tripoint &t, const pathfinding_settings &settings, const std::set< tripoint > &pre_closed={{ }}) const
 Calculate the best path using A*. More...
 
VehicleList get_vehicles ()
 
void add_vehicle_to_cache (vehicle *)
 
void clear_vehicle_point_from_cache (vehicle *veh, const tripoint &pt)
 
void update_vehicle_cache (vehicle *, int old_zlevel)
 
void reset_vehicle_cache ()
 
void clear_vehicle_cache ()
 
void clear_vehicle_list (int zlev)
 
void update_vehicle_list (const submap *to, int zlev)
 
bool check_vehicle_zones (int zlev)
 
std::vector< zone_data * > get_vehicle_zones (int zlev)
 
void register_vehicle_zone (vehicle *, int zlev)
 
bool deregister_vehicle_zone (zone_data &zone)
 
std::unique_ptr< vehicledetach_vehicle (vehicle *veh)
 
void destroy_vehicle (vehicle *veh)
 
void vehmove ()
 
bool vehproceed (VehicleList &vehicle_list)
 
VehicleList get_vehicles (const tripoint &start, const tripoint &end)
 
optional_vpart_position veh_at (const tripoint &p) const
 Checks if tile is occupied by vehicle and by which part. More...
 
vehicleveh_at_internal (const tripoint &p, int &part_num)
 
const vehicleveh_at_internal (const tripoint &p, int &part_num) const
 
void board_vehicle (const tripoint &p, player *pl)
 
void unboard_vehicle (const vpart_reference &, Character *passenger, bool dead_passenger=false)
 
void unboard_vehicle (const tripoint &p, bool dead_passenger=false)
 
bool displace_vehicle (vehicle &veh, const tripoint &dp)
 
void shift_vehicle_z (vehicle &veh, int z_shift)
 
bool displace_water (const tripoint &dp)
 
float vehicle_wheel_traction (const vehicle &veh, bool ignore_movement_modifiers=false) const
 
float vehicle_vehicle_collision (vehicle &veh, vehicle &veh2, const std::vector< veh_collision > &collisions)
 
units::angle shake_vehicle (vehicle &veh, int velocity_before, units::angle direction)
 
vehiclemove_vehicle (vehicle &veh, const tripoint &dp, const tileray &facing)
 
void set (const tripoint &p, const ter_id &new_terrain, const furn_id &new_furniture)
 
void set (const point &p, const ter_id &new_terrain, const furn_id &new_furniture)
 
std::string name (const tripoint &p)
 
std::string name (const point &p)
 
std::string disp_name (const tripoint &p)
 
std::string obstacle_name (const tripoint &p)
 Returns the name of the obstacle at p that might be blocking movement/projectiles/etc. More...
 
bool has_furn (const tripoint &p) const
 
bool has_furn (const point &p) const
 
furn_id furn (const tripoint &p) const
 
furn_id furn (const point &p) const
 
void furn_set (const tripoint &p, const furn_id &new_furniture, cata::poly_serialized< active_tile_data > new_active=nullptr)
 Sets the furniture at given position. More...
 
void furn_set (const point &p, const furn_id &new_furniture)
 
std::string furnname (const tripoint &p)
 
std::string furnname (const point &p)
 
bool can_move_furniture (const tripoint &pos, player *p=nullptr)
 
ter_id ter (const tripoint &p) const
 
ter_id ter (const point &p) const
 
uint8_t get_known_connections (const tripoint &p, int connect_group, const std::map< tripoint, ter_id > &override={}) const
 
const harvest_idget_harvest (const tripoint &p) const
 Returns the full harvest list, for spawning. More...
 
const std::set< std::string > & get_harvest_names (const tripoint &p) const
 Returns names of the items that would be dropped. More...
 
ter_id get_ter_transforms_into (const tripoint &p) const
 
furn_id get_furn_transforms_into (const tripoint &p) const
 
bool ter_set (const tripoint &p, const ter_id &new_terrain)
 
bool ter_set (const point &p, const ter_id &new_terrain)
 
std::string tername (const tripoint &p) const
 
std::string tername (const point &p) const
 
bool has_nearby_fire (const tripoint &p, int radius=1)
 
bool has_nearby_table (const tripoint &p, int radius=1)
 Check whether a table/workbench/vehicle kitchen or other flat surface is nearby that could be used for crafting or eating. More...
 
bool has_nearby_chair (const tripoint &p, int radius=1)
 Check whether a chair or vehicle seat is nearby. More...
 
bool sees_some_items (const tripoint &p, const Creature &who) const
 Check if creature can see some items at p. More...
 
bool sees_some_items (const tripoint &p, const tripoint &from) const
 
bool could_see_items (const tripoint &p, const Creature &who) const
 Check if the creature could see items at p if there were any items. More...
 
bool could_see_items (const tripoint &p, const tripoint &from) const
 
bool has_items (const tripoint &p) const
 Checks for existence of items. More...
 
void examine (Character &p, const tripoint &pos)
 Calls the examine function of furniture or terrain at given tile, for given character. More...
 
bool is_harvestable (const tripoint &pos) const
 Returns true if point at pos is harvestable right now, with no extra tools. More...
 
std::string features (const tripoint &p)
 
std::string features (const point &p)
 
bool has_flag (const std::string &flag, const tripoint &p) const
 
bool has_flag (const std::string &flag, const point &p) const
 
bool can_put_items (const tripoint &p) const
 
bool can_put_items (const point &p) const
 
bool can_put_items_ter_furn (const tripoint &p) const
 
bool can_put_items_ter_furn (const point &p) const
 
bool has_flag_ter (const std::string &flag, const tripoint &p) const
 
bool has_flag_ter (const std::string &flag, const point &p) const
 
bool has_flag_furn (const std::string &flag, const tripoint &p) const
 
bool has_flag_furn (const std::string &flag, const point &p) const
 
bool has_flag_ter_or_furn (const std::string &flag, const tripoint &p) const
 
bool has_flag_ter_or_furn (const std::string &flag, const point &p) const
 
bool has_flag (ter_bitflags flag, const tripoint &p) const
 
bool has_flag (ter_bitflags flag, const point &p) const
 
bool has_flag_ter (ter_bitflags flag, const tripoint &p) const
 
bool has_flag_ter (ter_bitflags flag, const point &p) const
 
bool has_flag_furn (ter_bitflags flag, const tripoint &p) const
 
bool has_flag_furn (ter_bitflags flag, const point &p) const
 
bool has_flag_ter_or_furn (ter_bitflags flag, const tripoint &p) const
 
bool has_flag_ter_or_furn (ter_bitflags flag, const point &p) const
 
bool is_bashable (const tripoint &p, bool allow_floor=false) const
 Returns true if there is a bashable vehicle part or the furn/terrain is bashable at p. More...
 
bool is_bashable (const point &p) const
 
bool is_bashable_ter (const tripoint &p, bool allow_floor=false) const
 Returns true if the terrain at p is bashable. More...
 
bool is_bashable_ter (const point &p) const
 
bool is_bashable_furn (const tripoint &p) const
 Returns true if the furniture at p is bashable. More...
 
bool is_bashable_furn (const point &p) const
 
bool is_bashable_ter_furn (const tripoint &p, bool allow_floor=false) const
 Returns true if the furniture or terrain at p is bashable. More...
 
bool is_bashable_ter_furn (const point &p) const
 
int bash_strength (const tripoint &p, bool allow_floor=false) const
 Returns max_str of the furniture or terrain at p. More...
 
int bash_strength (const point &p) const
 
int bash_resistance (const tripoint &p, bool allow_floor=false) const
 Returns min_str of the furniture or terrain at p. More...
 
int bash_resistance (const point &p) const
 
int bash_rating (int str, const tripoint &p, bool allow_floor=false) const
 Returns a success rating from -1 to 10 for a given tile based on a set strength, used for AI movement planning Values roughly correspond to 10% increment chances of success on a given bash, rounded down. More...
 
int bash_rating (const int str, const point &p) const
 
void make_rubble (const tripoint &p, const furn_id &rubble_type, bool items, const ter_id &floor_type, bool overwrite=false)
 Generates rubble at the given location, if overwrite is true it just writes on top of what currently exists floor_type is only used if there is a non-bashable wall at the location or with overwrite = true. More...
 
void make_rubble (const tripoint &p, const furn_id &rubble_type, bool items)
 
void make_rubble (const tripoint &p)
 
bool is_outside (const tripoint &p) const
 
bool is_outside (const point &p) const
 
bool is_divable (const tripoint &p) const
 Returns whether or not the terrain at the given location can be dived into (by monsters that can swim or are aquatic or non-breathing). More...
 
bool is_divable (const point &p) const
 
bool is_water_shallow_current (const tripoint &p) const
 
bool is_water_shallow_current (const point &p) const
 
bool is_last_ter_wall (bool no_furn, const point &p, const point &max, direction dir) const
 Check if the last terrain is wall in direction NORTH, SOUTH, WEST or EAST. More...
 
bool tinder_at (const tripoint &p)
 Checks if there are any tinder flagged items on the tile. More...
 
bool flammable_items_at (const tripoint &p, int threshold=0)
 Checks if there are any flammable items on the tile. More...
 
bool is_flammable (const tripoint &p)
 Returns true if there is a flammable item or field or the furn/terrain is flammable at p. More...
 
point random_outdoor_tile ()
 
void draw_line_ter (const ter_id &type, const point &p1, const point &p2)
 
void draw_line_furn (const furn_id &type, const point &p1, const point &p2)
 
void draw_fill_background (const ter_id &type)
 
void draw_fill_background (ter_id(*f)())
 
void draw_fill_background (const weighted_int_list< ter_id > &f)
 
void draw_square_ter (const ter_id &type, const point &p1, const point &p2)
 
void draw_square_furn (const furn_id &type, const point &p1, const point &p2)
 
void draw_square_ter (ter_id(*f)(), const point &p1, const point &p2)
 
void draw_square_ter (const weighted_int_list< ter_id > &f, const point &p1, const point &p2)
 
void draw_rough_circle_ter (const ter_id &type, const point &p, int rad)
 
void draw_rough_circle_furn (const furn_id &type, const point &p, int rad)
 
void draw_circle_ter (const ter_id &type, const rl_vec2d &p, double rad)
 
void draw_circle_ter (const ter_id &type, const point &p, int rad)
 
void draw_circle_furn (const furn_id &type, const point &p, int rad)
 
void add_corpse (const tripoint &p)
 
void translate (const ter_id &from, const ter_id &to)
 
void translate_radius (const ter_id &from, const ter_id &to, float radi, const tripoint &p, bool same_submap=false, bool toggle_between=false)
 
bool close_door (const tripoint &p, bool inside, bool check_only)
 
bool open_door (const tripoint &p, bool inside, bool check_only=false)
 
void batter (const tripoint &p, int power, int tries=1, bool silent=false)
 bash a square for a set number of times at set power. More...
 
void destroy (const tripoint &p, bool silent=false)
 Keeps bashing a square until it can't be bashed anymore. More...
 
void destroy_furn (const tripoint &p, bool silent=false)
 Keeps bashing a square until there is no more furniture. More...
 
void crush (const tripoint &p)
 
void shoot (const tripoint &p, projectile &proj, bool hit_items)
 
int collapse_check (const tripoint &p)
 Checks if a square should collapse, returns the X for the one_in(X) collapse chance. More...
 
void collapse_at (const tripoint &p, bool silent, bool was_supporting=false, bool destroy_pos=true)
 Causes a collapse at p, such as from destroying a wall. More...
 
void propagate_suspension_check (const tripoint &point)
 Checks surrounding tiles for suspension, and has them check for collapse. More...
 
void collapse_invalid_suspension (const tripoint &point)
 Triggers a recursive collapse of suspended tiles based on their support validity. More...
 
bool is_suspension_valid (const tripoint &point)
 Checks the four orientations in which a suspended tile could be valid, and returns if the tile is valid. More...
 
void smash_items (const tripoint &p, int power, const std::string &cause_message, bool do_destroy)
 Tries to smash the items at the given tripoint. More...
 
bash_results bash (const tripoint &p, int str, bool silent=false, bool destroy=false, bool bash_floor=false, const vehicle *bashing_vehicle=nullptr)
 Returns a pair where first is whether anything was smashed and second is if it was destroyed. More...
 
bash_results bash_vehicle (const tripoint &p, const bash_params &params)
 
bash_results bash_ter_furn (const tripoint &p, const bash_params &params)
 
bool hit_with_acid (const tripoint &p)
 
bool hit_with_fire (const tripoint &p)
 
bool has_adjacent_furniture_with (const tripoint &p, const std::function< bool(const furn_t &)> &filter)
 Returns true if there is furniture for which filter returns true in a 1 tile radius of p. More...
 
bool mop_spills (const tripoint &p)
 Remove moppable fields/items at this location. More...
 
void decay_fields_and_scent (const time_duration &amount)
 Moved here from weather.cpp for speed. More...
 
std::string get_signage (const tripoint &p) const
 
void set_signage (const tripoint &p, const std::string &message) const
 
void delete_signage (const tripoint &p) const
 
int get_radiation (const tripoint &p) const
 
void set_radiation (const tripoint &p, int value)
 
void set_radiation (const point &p, const int value)
 
void adjust_radiation (const tripoint &p, int delta)
 Increment the radiation in the given tile by the given delta (decrement it if delta is negative) More...
 
void adjust_radiation (const point &p, const int delta)
 
int get_temperature (const tripoint &p) const
 
void set_temperature (const tripoint &p, int temperature)
 
void set_temperature (const point &p, int new_temperature)
 
std::vector< tripointcheck_submap_active_item_consistency ()
 
map_stack i_at (const tripoint &p)
 
map_stack i_at (const point &p)
 
item water_from (const tripoint &p)
 
void i_clear (const tripoint &p)
 
void i_clear (const point &p)
 
map_stack::iterator i_rem (const tripoint &p, map_stack::const_iterator it)
 
map_stack::iterator i_rem (const point &location, map_stack::const_iterator it)
 
void i_rem (const tripoint &p, item *it)
 
void i_rem (const point &p, item *it)
 
void spawn_artifact (const tripoint &p)
 
void spawn_natural_artifact (const tripoint &p, artifact_natural_property prop)
 
void spawn_item (const tripoint &p, const itype_id &type_id, unsigned quantity=1, int charges=0, const time_point &birthday=calendar::start_of_cataclysm, int damlevel=0)
 
void spawn_item (const point &p, const itype_id &type_id, unsigned quantity=1, int charges=0, const time_point &birthday=calendar::start_of_cataclysm, int damlevel=0)
 
void spawn_item (const tripoint &p, const std::string &type_id, unsigned quantity=1, int charges=0, const time_point &birthday=calendar::start_of_cataclysm, int damlevel=0)
 
void spawn_item (const point &p, const std::string &type_id, unsigned quantity=1, int charges=0, const time_point &birthday=calendar::start_of_cataclysm, int damlevel=0)
 
units::volume max_volume (const tripoint &p)
 
units::volume free_volume (const tripoint &p)
 
units::volume stored_volume (const tripoint &p)
 
itemadd_item_or_charges (const tripoint &pos, item obj, bool overflow=true)
 Adds an item to map tile or stacks charges. More...
 
itemadd_item_or_charges (const point &p, item obj, bool overflow=true)
 
itemadd_item (const tripoint &p, item new_item)
 Place an item on the map, despite the parameter name, this is not necessarily a new item. More...
 
void add_item (const point &p, item new_item)
 
itemspawn_an_item (const tripoint &p, item new_item, int charges, int damlevel)
 
void spawn_an_item (const point &p, item new_item, int charges, int damlevel)
 
void make_active (item_location &loc)
 Update an item's active status, for example when adding hot or perishable liquid to a container. More...
 
void update_lum (item_location &loc, bool add)
 Update luminosity before and after item's transformation. More...
 

Static Public Member Functions

static apparent_light_info apparent_light_helper (const level_cache &map_cache, const tripoint &p)
 Helper function for light claculation; exposed here for map editor. More...
 

Private Member Functions

maptile maptile_at_internal (const tripoint &p) const
 
maptile maptile_at_internal (const tripoint &p)
 
std::pair< tripoint, maptilemaptile_has_bounds (const tripoint &p, bool bounds_checked)
 
std::array< std::pair< tripoint, maptile >, 8 > get_neighbors (const tripoint &p)
 
void spread_gas (field_entry &cur, const tripoint &p, int percent_spread, const time_duration &outdoor_age_speedup, scent_block &sblk)
 
void create_hot_air (const tripoint &p, int intensity)
 
bool gas_can_spread_to (field_entry &cur, const maptile &dst)
 
void gas_spread_to (field_entry &cur, maptile &dst, const tripoint &p)
 
int burn_body_part (player &u, field_entry &cur, body_part bp, int scale)
 
bool sees (const tripoint &F, const tripoint &T, int range, int &bresenham_slope) const
 Don't expose the slope adjust outside map functions. More...
 

Friends

class editmap
 
class visitable< map_cursor >
 

Consume items on the map

The functions here consume accessible items / item charges on the map or in vehicles around the player (whose positions is given as origin).

They return a list of copies of the consumed items (with the actually consumed charges in it). The quantity / amount parameter will be reduced by the number of items/charges removed. If all required items could be removed from the map, the quantity/amount will be 0, otherwise it will contain a positive value and the remaining items must be gathered from somewhere else.

enum  iteration_state { ITER_CONTINUE = 0 , ITER_SKIP_SUBMAP , ITER_SKIP_ZLEVEL , ITER_FINISH }
 Enum used by functors in function_over to control execution. More...
 
std::set< tripointsupport_cache_dirty
 
std::vector< submap * > grid
 The list of currently loaded submaps. More...
 
std::vector< std::vector< tripoint > > traplocs
 This vector contains an entry for each trap type, it has therefor the same size as the traplist vector. More...
 
std::vector< tripointfield_furn_locs
 Vector of tripoints containing active field-emitting furniture. More...
 
std::array< std::unique_ptr< level_cache >, OVERMAP_LAYERScaches
 Holds caches for visibility, light, transparency and vehicles. More...
 
std::array< std::unique_ptr< pathfinding_cache >, OVERMAP_LAYERSpathfinding_caches
 
std::set< tripointsubmaps_with_active_items
 Set of submaps that contain active items in absolute coordinates. More...
 
lru_cache< point, char > skew_vision_cache
 Cache of coordinate pairs recently checked for visibility. More...
 
VehicleList last_full_vehicle_list
 Vehicle list doesn't change often, but is pretty expensive. More...
 
bool last_full_vehicle_list_dirty = true
 
visibility_variables visibility_variables_cache
 
cata::optional< std::pair< tripoint, int > > max_populated_zlev = cata::nullopt
 
std::set< vehicle * > dirty_vehicle_list
 
int my_MAPSIZE
 
bool zlevels
 
tripoint abs_sub
 Absolute coordinates of first submap (get_submap_at(0,0)) This is in submap coordinates (see overmapbuffer for explanation). More...
 
std::list< itemuse_amount_square (const tripoint &p, const itype_id &type, int &quantity, const std::function< bool(const item &)> &filter=return_true< item >)
 
std::list< itemuse_amount (const tripoint &origin, int range, const itype_id &type, int &quantity, const std::function< bool(const item &)> &filter=return_true< item >)
 
std::list< itemuse_charges (const tripoint &origin, int range, const itype_id &type, int &quantity, const std::function< bool(const item &)> &filter=return_true< item >, basecamp *bcp=nullptr)
 
std::vector< item * > place_items (const item_group_id &loc, int chance, const tripoint &p1, const tripoint &p2, bool ongrass, const time_point &turn, int magazine=0, int ammo=0)
 Place items from item group in the rectangle f - t. More...
 
std::vector< item * > place_items (const item_group_id &loc, int chance, const point &p1, const point &p2, bool ongrass, const time_point &turn, int magazine=0, int ammo=0)
 
std::vector< item * > put_items_from_loc (const item_group_id &loc, const tripoint &p, const time_point &turn=calendar::start_of_cataclysm)
 Place items from an item group at p. More...
 
std::vector< item * > spawn_items (const tripoint &p, const std::vector< item > &new_items)
 
void spawn_items (const point &p, const std::vector< item > &new_items)
 
void create_anomaly (const tripoint &p, artifact_natural_property prop, bool create_rubble=true)
 
void create_anomaly (const point &cp, artifact_natural_property prop, bool create_rubble=true)
 
void partial_con_set (const tripoint &p, const partial_con &con)
 
void partial_con_remove (const tripoint &p)
 
partial_conpartial_con_at (const tripoint &p)
 
void trap_set (const tripoint &p, const trap_id &type)
 
const traptr_at (const tripoint &p) const
 
bool can_see_trap_at (const tripoint &p, const Character &c) const
 See trap::can_see, which is called for the trap here. More...
 
void disarm_trap (const tripoint &p)
 
void remove_trap (const tripoint &p)
 
const std::vector< tripoint > & get_furn_field_locations () const
 
const std::vector< tripoint > & trap_locations (const trap_id &type) const
 
void create_burnproducts (const tripoint &p, const item &fuel, const units::mass &burned_mass)
 
void process_fields ()
 
void process_fields_in_submap (submap *current_submap, const tripoint &submap_pos)
 
void creature_in_field (Creature &critter)
 Apply field effects to the creature when it's on a square with fields. More...
 
void creature_on_trap (Creature &critter, bool may_avoid=true)
 Apply trap effects to the creature, similar to creature_in_field. More...
 
const fieldfield_at (const tripoint &p) const
 Get the fields that are here. More...
 
fieldfield_at (const tripoint &p)
 Gets fields that are here. More...
 
time_duration get_field_age (const tripoint &p, const field_type_id &type) const
 Get the age of a field entry (field_entry::age), if there is no field of that type, returns -1_turns. More...
 
int get_field_intensity (const tripoint &p, const field_type_id &type) const
 Get the intensity of a field entry (field_entry::intensity), if there is no field of that type, returns 0. More...
 
time_duration mod_field_age (const tripoint &p, const field_type_id &type, const time_duration &offset)
 Increment/decrement age of field entry at point. More...
 
int mod_field_intensity (const tripoint &p, const field_type_id &type, int offset)
 Increment/decrement intensity of field entry at point, creating if not present, removing if intensity becomes 0. More...
 
time_duration set_field_age (const tripoint &p, const field_type_id &type, const time_duration &age, bool isoffset=false)
 Set age of field entry at point. More...
 
int set_field_intensity (const tripoint &p, const field_type_id &type, int new_intensity, bool isoffset=false)
 Set intensity of field entry at point, creating if not present, removing if intensity becomes 0. More...
 
field_entryget_field (const tripoint &p, const field_type_id &type)
 Get field of specific type at point. More...
 
bool dangerous_field_at (const tripoint &p)
 
bool add_field (const tripoint &p, const field_type_id &type_id, int intensity=INT_MAX, const time_duration &age=0_turns, bool hit_player=true)
 Add field entry at point, or set intensity if present. More...
 
void remove_field (const tripoint &p, const field_type_id &field_to_remove)
 Remove field entry at xy, ignored if the field entry is not present. More...
 
void add_splatter (const field_type_id &type, const tripoint &where, int intensity=1)
 
void add_splatter_trail (const field_type_id &type, const tripoint &from, const tripoint &to)
 
void add_splash (const field_type_id &type, const tripoint &center, int radius, int intensity)
 
void propagate_field (const tripoint &center, const field_type_id &type, int amount, int max_intensity=0)
 
void emit_field (const tripoint &pos, const emit_id &src, float mul=1.0f)
 Runs one cycle of emission src which may result in propagation of fields. More...
 
void scent_blockers (std::array< std::array< bool, MAPSIZE_X >, MAPSIZE_Y > &blocks_scent, std::array< std::array< bool, MAPSIZE_X >, MAPSIZE_Y > &reduces_scent, const point &min, const point &max)
 Build the map of scent-resistant tiles. More...
 
computercomputer_at (const tripoint &p)
 
computeradd_computer (const tripoint &p, const std::string &name, int security)
 
void add_camp (const tripoint_abs_omt &omt_pos, const std::string &name)
 
void remove_submap_camp (const tripoint &)
 
basecamp hoist_submap_camp (const tripoint &p)
 
bool point_within_camp (const tripoint &point_check) const
 
bool has_graffiti_at (const tripoint &p) const
 
const std::string & graffiti_at (const tripoint &p) const
 
void set_graffiti (const tripoint &p, const std::string &contents)
 
void delete_graffiti (const tripoint &p)
 
int climb_difficulty (const tripoint &p) const
 Checks 3x3 block centered on p for terrain to climb. More...
 
bool has_floor (const tripoint &p) const
 
bool supports_above (const tripoint &p) const
 Does this tile support vehicles and furniture above it. More...
 
bool has_floor_or_support (const tripoint &p) const
 
void drop_everything (const tripoint &p)
 Handles map objects of given type (not creatures) falling down. More...
 
void drop_furniture (const tripoint &p)
 
void drop_items (const tripoint &p)
 
void drop_vehicle (const tripoint &p)
 
void drop_fields (const tripoint &p)
 
void process_falling ()
 Invoked drop_everything on cached dirty tiles. More...
 
bool is_cornerfloor (const tripoint &p) const
 
void generate (const tripoint &p, const time_point &when)
 
void place_spawns (const mongroup_id &group, int chance, const point &p1, const point &p2, float density, bool individual=false, bool friendly=false, const std::string &name="NONE", int mission_id=-1)
 
void place_gas_pump (const point &p, int charges, const std::string &fuel_type)
 
void place_gas_pump (const point &p, int charges)
 
void place_toilet (const point &p, int charges=6 *4)
 
void place_vending (const point &p, const item_group_id &type, bool reinforced=false)
 
character_id place_npc (const point &p, const string_id< npc_template > &type, bool force=false)
 
void apply_faction_ownership (const point &p1, const point &p2, const faction_id &id)
 
void add_spawn (const mtype_id &type, int count, const tripoint &p, bool friendly=false, int faction_id=-1, int mission_id=-1, const std::string &name="NONE") const
 
void do_vehicle_caching (int z)
 
void build_map_cache (int zlev, bool skip_lightmap=false)
 
void build_obstacle_cache (const tripoint &start, const tripoint &end, float(&obstacle_cache)[MAPSIZE_X][MAPSIZE_Y])
 
vehicleadd_vehicle (const vgroup_id &type, const tripoint &p, units::angle dir, int init_veh_fuel=-1, int init_veh_status=-1, bool merge_wrecks=true)
 
vehicleadd_vehicle (const vgroup_id &type, const point &p, units::angle dir, int init_veh_fuel=-1, int init_veh_status=-1, bool merge_wrecks=true)
 
vehicleadd_vehicle (const vproto_id &type, const tripoint &p, units::angle dir, int init_veh_fuel=-1, int init_veh_status=-1, bool merge_wrecks=true)
 
vehicleadd_vehicle (const vproto_id &type, const point &p, units::angle dir, int init_veh_fuel=-1, int init_veh_status=-1, bool merge_wrecks=true)
 
float light_transparency (const tripoint &p) const
 
lit_level light_at (const tripoint &p) const
 
float ambient_light_at (const tripoint &p) const
 
bool is_transparent (const tripoint &p) const
 Returns whether the tile at p is transparent(you can look past it). More...
 
bool pl_sees (const tripoint &t, int max_range) const
 Whether the player character (g->u) can see the given square (local map coordinates). More...
 
bool pl_line_of_sight (const tripoint &t, int max_range) const
 Uses the map cache to tell if the player could see the given square. More...
 
tripoint get_abs_sub () const
 return abs_sub More...
 
tripoint getabs (const tripoint &p) const
 Translates local (to this map) coordinates of a square to global absolute coordinates. More...
 
point getabs (const point &p) const
 
tripoint getlocal (const tripoint &p) const
 Inverse of getabs. More...
 
point getlocal (const point &p) const
 
virtual bool inbounds (const tripoint &p) const
 
bool inbounds (const point &p) const
 
bool inbounds_z (const int z) const
 
void clip_to_bounds (tripoint &p) const
 Clips the coordinates of p to fit the map bounds. More...
 
void clip_to_bounds (int &x, int &y) const
 
void clip_to_bounds (int &x, int &y, int &z) const
 
int getmapsize () const
 
bool has_zlevels () const
 
void rotate (int turns, bool setpos_safe=false)
 Rotates this map, and all of its contents, by the specified multiple of 90 degrees. More...
 
void spawn_monsters (bool ignore_sight)
 Spawn monsters from submap spawn points and from the overmap. More...
 
void rotten_item_spawn (const item &item, const tripoint &p)
 Checks to see if the item that is rotting away generates a creature when it does. More...
 
void build_outside_cache (int zlev)
 
bool build_floor_cache (int zlev)
 
void build_floor_caches ()
 
void update_suspension_cache (const int &z)
 
bash_results bash_items (const tripoint &p, const bash_params &params)
 
bash_results bash_field (const tripoint &p, const bash_params &params)
 
bash_results bash_ter_success (const tripoint &p, const bash_params &params)
 
bash_results bash_furn_success (const tripoint &p, const bash_params &params)
 
void process_items ()
 
const level_cacheget_cache_ref (int zlev) const
 
const pathfinding_cacheget_pathfinding_cache_ref (int zlev) const
 
void update_pathfinding_cache (int zlev) const
 
void update_visibility_cache (int zlev)
 
const visibility_variablesget_visibility_variables_cache () const
 
void update_submap_active_item_status (const tripoint &p)
 
const std::set< tripoint > & get_submaps_with_active_items () const
 
tripoint_range< tripointpoints_in_rectangle (const tripoint &from, const tripoint &to) const
 
tripoint_range< tripointpoints_in_radius (const tripoint &center, size_t radius, size_t radiusz=0) const
 
tripoint_range< tripointpoints_on_zlevel () const
 Yields a range of all points that are contained in the map and have the z-level of this map (abs_sub). More...
 
tripoint_range< tripointpoints_on_zlevel (int z) const
 Same as above, but uses the specific z-level. More...
 
std::list< item_locationget_active_items_in_radius (const tripoint &center, int radius) const
 
std::list< item_locationget_active_items_in_radius (const tripoint &center, int radius, special_item_type type) const
 
std::list< tripointfind_furnitures_with_flag_in_radius (const tripoint &center, size_t radius, const std::string &flag, size_t radiusz=0)
 returns positions of furnitures with matching flag in the specified radius More...
 
std::list< Creature * > get_creatures_in_radius (const tripoint &center, size_t radius, size_t radiusz=0)
 returns creatures in specified radius More...
 
level_cacheaccess_cache (int zlev)
 
const level_cacheaccess_cache (int zlev) const
 
bool dont_draw_lower_floor (const tripoint &p)
 
void support_dirty (const tripoint &p)
 
void spawn_monsters_submap (const tripoint &gp, bool ignore_sight)
 
void spawn_monsters_submap_group (const tripoint &gp, mongroup &group, bool ignore_sight)
 
fieldget_field (const tripoint &p)
 
submapgetsubmap (size_t grididx) const
 Get the submap pointer with given index in grid, the index must be valid! More...
 
submapget_submap_at (const tripoint &p) const
 Get the submap pointer containing the specified position within the reality bubble. More...
 
submapget_submap_at (const point &p) const
 
submapget_submap_at (const tripoint &p, point &offset_p) const
 Get the submap pointer containing the specified position within the reality bubble. More...
 
submapget_submap_at (const point &p, point &offset_p) const
 
submapget_submap_at_grid (const point &gridp) const
 Get submap pointer in the grid at given grid coordinates. More...
 
submapget_submap_at_grid (const tripoint &gridp) const
 
int calc_max_populated_zlev ()
 Caclulate the greatest populated zlevel in the loaded submaps and save in the level cache. More...
 
void invalidate_max_populated_zlev (int zlev)
 Conditionally invalidates max_pupulated_zlev cache if the submap uniformity change occurs above current max_pupulated_zlev value. More...
 
int move_cost_internal (const furn_t &furniture, const ter_t &terrain, const vehicle *veh, int vpart) const
 Internal versions of public functions to avoid checking same variables multiple times. More...
 
int bash_rating_internal (int str, const furn_t &furniture, const ter_t &terrain, bool allow_floor, const vehicle *veh, int part) const
 
bool draw_maptile (const catacurses::window &w, const tripoint &p, const maptile &tile, const drawsq_params &params) const
 Internal version of the drawsq. More...
 
void draw_from_above (const catacurses::window &w, const tripoint &p, const maptile &tile, const drawsq_params &params) const
 Draws the tile as seen from above. More...
 
int determine_wall_corner (const tripoint &p) const
 
void apply_light_source (const tripoint &p, float luminance)
 
void add_light_source (const tripoint &p, float luminance)
 
void apply_directional_light (const tripoint &p, int direction, float luminance)
 
void apply_light_arc (const tripoint &p, units::angle, float luminance, units::angle wideangle=30_degrees)
 
void apply_light_ray (bool lit[MAPSIZE_X][MAPSIZE_Y], const tripoint &s, const tripoint &e, float luminance)
 
void add_light_from_items (const tripoint &p, item_stack::iterator begin, item_stack::iterator end)
 
std::unique_ptr< vehicleadd_vehicle_to_map (std::unique_ptr< vehicle > veh, bool merge_wrecks)
 Takes a vehicle already created with new and attempts to place it on the map, checking for collisions. More...
 
ter_id get_roof (const tripoint &p, bool allow_air) const
 
void process_items_in_submap (submap &current_submap, const tripoint &gridp)
 
void process_items_in_vehicles (submap &current_submap)
 
void process_items_in_vehicle (vehicle &cur_veh, submap &current_submap)
 
template<typename Functor >
void function_over (const tripoint &start, const tripoint &end, Functor fun) const
 Runs a functor over given submaps over submaps in the area, getting next submap only when the current one "runs out" rather than every time. More...
 
level_cacheget_cache (int zlev) const
 
pathfinding_cacheget_pathfinding_cache (int zlev) const
 
void saven (const tripoint &grid)
 
void loadn (const tripoint &grid, bool update_vehicles)
 
void loadn (const point &grid, bool update_vehicles)
 
void actualize (const tripoint &grid)
 Fast forward a submap that has just been loading into this map. More...
 
void add_roofs (const tripoint &grid)
 Hacks in missing roofs. More...
 
template<typename Container >
void remove_rotten_items (Container &items, const tripoint &p)
 Go through the list of items, update their rotten status and remove items that have rotten away completely. More...
 
void fill_funnels (const tripoint &p, const time_point &since)
 Try to fill funnel based items here. More...
 
void grow_plant (const tripoint &p)
 Try to grow a harvestable plant to the next stage(s). More...
 
void restock_fruits (const tripoint &p, const time_duration &time_since_last_actualize)
 Try to grow fruits on static plants (not planted by the player) More...
 
void produce_sap (const tripoint &p, const time_duration &time_since_last_actualize)
 Produce sap on tapped maple trees. More...
 
void rad_scorch (const tripoint &p, const time_duration &time_since_last_actualize)
 Radiation-related plant (and fungus?) death. More...
 
void decay_cosmetic_fields (const tripoint &p, const time_duration &time_since_last_actualize)
 
void player_in_field (player &u)
 
void monster_in_field (monster &z)
 
void shift_traps (const tripoint &shift)
 As part of the map shifting, this shifts the trap locations stored in traplocs. More...
 
void copy_grid (const tripoint &to, const tripoint &from)
 
void draw_map (mapgendata &dat)
 
void draw_office_tower (mapgendata &dat)
 
void draw_lab (mapgendata &dat)
 
void draw_temple (mapgendata &dat)
 
void draw_mine (mapgendata &dat)
 
void draw_anthill (mapgendata &dat)
 
void draw_slimepit (mapgendata &dat)
 
void draw_triffid (mapgendata &dat)
 
void draw_connections (mapgendata &dat)
 
bool build_transparency_cache (int zlev)
 
bool build_vision_transparency_cache (int zlev)
 
void build_sunlight_cache (int pzlev)
 
void generate_lightmap (int zlev)
 
void build_seen_cache (const tripoint &origin, int target_z)
 Calculates the Field Of View for the provided map from the given x, y coordinates. More...
 
void apply_character_light (Character &p)
 
void set_abs_sub (const tripoint &p)
 Sets abs_sub, see there. More...
 
size_t get_nonant (const tripoint &gridp) const
 Get the index of a submap pointer in the grid given by grid coordinates. More...
 
size_t get_nonant (const point &gridp) const
 
void setsubmap (size_t grididx, submap *smap)
 Set the submap pointer in grid at the give index. More...
 

Detailed Description

Manage and cache data about a part of the map.

Despite the name, this class isn't actually responsible for managing the map as a whole. For that function, see mapbuffer. Instead, this class loads a part of the mapbuffer into a cache, and adds certain temporary information such as lighting calculations to it.

To understand the following descriptions better, you should also read Map Management

The map coordinates always start at (0, 0) for the top-left and end at (map_width-1, map_height-1) for the bottom-right.

The actual map data is stored in submap instances. These instances are managed by mapbuffer. References to the currently active submaps are stored in map::grid: 0 1 2 3 4 5 6 7 8 In this example, the top-right submap would be at grid[2].

When the player moves between submaps, the whole map is shifted, so that if the player moves one submap to the right, (0, 0) now points to a tile one submap to the right from before

Definition at line 371 of file map.h.

Member Enumeration Documentation

◆ iteration_state

enum map::iteration_state
private

Enum used by functors in function_over to control execution.

Enumerator
ITER_CONTINUE 
ITER_SKIP_SUBMAP 
ITER_SKIP_ZLEVEL 
ITER_FINISH 

Definition at line 1937 of file map.h.

1937 {
1938 ITER_CONTINUE = 0, // Keep iterating
1939 ITER_SKIP_SUBMAP, // Skip the rest of this submap
1940 ITER_SKIP_ZLEVEL, // Skip the rest of this z-level
1941 ITER_FINISH // End iteration
1942 };
@ ITER_SKIP_ZLEVEL
Definition: map.h:1940
@ ITER_SKIP_SUBMAP
Definition: map.h:1939
@ ITER_CONTINUE
Definition: map.h:1938
@ ITER_FINISH
Definition: map.h:1941

Constructor & Destructor Documentation

◆ map() [1/2]

map::map ( int  mapsize = MAPSIZE,
bool  zlev = false 
)

Definition at line 170 of file map.cpp.

171{
172 my_MAPSIZE = mapsize;
173 zlevels = zlev;
174 if( zlevels ) {
175 grid.resize( static_cast<size_t>( my_MAPSIZE * my_MAPSIZE * OVERMAP_LAYERS ), nullptr );
176 } else {
177 grid.resize( static_cast<size_t>( my_MAPSIZE * my_MAPSIZE ), nullptr );
178 }
179
180 for( auto &ptr : caches ) {
181 ptr = std::make_unique<level_cache>();
182 }
183
184 for( auto &ptr : pathfinding_caches ) {
185 ptr = std::make_unique<pathfinding_cache>();
186 }
187
188 dbg( DL::Info ) << "map::map(): my_MAPSIZE: " << my_MAPSIZE << " z-levels enabled:" << zlevels;
189 traplocs.resize( trap::count() );
190}
std::vector< std::vector< tripoint > > traplocs
This vector contains an entry for each trap type, it has therefor the same size as the traplist vecto...
Definition: map.h:1969
std::array< std::unique_ptr< pathfinding_cache >, OVERMAP_LAYERS > pathfinding_caches
Definition: map.h:1979
std::vector< submap * > grid
The list of currently loaded submaps.
Definition: map.h:1962
int my_MAPSIZE
Definition: map.h:1794
bool zlevels
Definition: map.h:1795
std::array< std::unique_ptr< level_cache >, OVERMAP_LAYERS > caches
Holds caches for visibility, light, transparency and vehicles.
Definition: map.h:1977
@ Info
Information (default: enabled).
const void * ptr(const T *p)
\rst Converts p to const void* for pointer formatting.
static constexpr int OVERMAP_LAYERS
#define dbg(x)
Definition: map.cpp:136
static size_t count()
Definition: trap.cpp:95

References caches, trap::count(), dbg, grid, Info, my_MAPSIZE, OVERMAP_LAYERS, pathfinding_caches, ptr(), traplocs, and zlevels.

Referenced by check_submap_active_item_consistency().

◆ map() [2/2]

map::map ( bool  zlev)
inlineexplicit

Definition at line 379 of file map.h.

379: map( MAPSIZE, zlev ) { }
map(int mapsize=MAPSIZE, bool zlev=false)
Definition: map.cpp:170
static constexpr int MAPSIZE

◆ ~map()

map::~map ( )
virtualdefault

Member Function Documentation

◆ access_cache() [1/2]

level_cache & map::access_cache ( int  zlev)

Definition at line 8522 of file map.cpp.

8523{
8524 if( zlev >= -OVERMAP_DEPTH && zlev <= OVERMAP_HEIGHT ) {
8525 return *caches[zlev + OVERMAP_DEPTH];
8526 }
8527
8528 debugmsg( "access_cache called with invalid z-level: %d", zlev );
8529 return nullcache;
8530}
#define debugmsg(...)
Debug message of level DL::Error and class DC::DebugMsg, also includes the source file name and line,...
Definition: debug.h:74
static constexpr int OVERMAP_HEIGHT
static constexpr int OVERMAP_DEPTH
static level_cache nullcache
Definition: map.cpp:140

References caches, debugmsg, nullcache, OVERMAP_DEPTH, and OVERMAP_HEIGHT.

Referenced by get_known_connections(), game::place_player_overmap(), process_items(), and game::vertical_shift().

◆ access_cache() [2/2]

const level_cache & map::access_cache ( int  zlev) const

Definition at line 8532 of file map.cpp.

8533{
8534 if( zlev >= -OVERMAP_DEPTH && zlev <= OVERMAP_HEIGHT ) {
8535 return *caches[zlev + OVERMAP_DEPTH];
8536 }
8537
8538 debugmsg( "access_cache called with invalid z-level: %d", zlev );
8539 return nullcache;
8540}

References caches, debugmsg, nullcache, OVERMAP_DEPTH, and OVERMAP_HEIGHT.

◆ accessible_items()

bool map::accessible_items ( const tripoint t) const

Check whether the player can access the items located .

Certain furniture/terrain may prevent that (e.g. a locked safe).

Definition at line 6440 of file map.cpp.

6441{
6442 return !has_flag( "SEALED", t ) || has_flag( "LIQUIDCONT", t );
6443}
bool has_flag(const std::string &flag, const tripoint &p) const
Definition: map.cpp:2288

References has_flag().

Referenced by basecamp::form_crafting_inventory(), inventory::form_from_map(), player::get_eligible_containers_for_crafting(), has_clear_path_to_pickup_items(), try_fuel_fire(), and use_charges().

◆ actualize()

void map::actualize ( const tripoint grid)
protected

Fast forward a submap that has just been loading into this map.

This is used to rot and remove rotten items, grow plants, fill funnels etc.

Definition at line 7264 of file map.cpp.

7265{
7266 submap *const tmpsub = get_submap_at_grid( grid );
7267 if( tmpsub == nullptr ) {
7268 debugmsg( "Actualize called on null submap (%d,%d,%d)", grid.x, grid.y, grid.z );
7269 return;
7270 }
7271
7272 const time_duration time_since_last_actualize = calendar::turn - tmpsub->last_touched;
7273 const bool do_funnels = ( grid.z >= 0 );
7274
7275 // check spoiled stuff, and fill up funnels while we're at it
7276 for( int x = 0; x < SEEX; x++ ) {
7277 for( int y = 0; y < SEEY; y++ ) {
7278 const tripoint pnt = sm_to_ms_copy( grid ) + point( x, y );
7279 const point p( x, y );
7280 const auto &furn = this->furn( pnt ).obj();
7281 if( furn.has_flag( "EMITTER" ) ) {
7282 field_furn_locs.push_back( pnt );
7283 }
7284 // plants contain a seed item which must not be removed under any circumstances
7285 if( !furn.has_flag( "DONT_REMOVE_ROTTEN" ) ) {
7286 remove_rotten_items( tmpsub->get_items( { x, y } ), pnt );
7287 }
7288
7289 const auto trap_here = tmpsub->get_trap( p );
7290 if( trap_here != tr_null ) {
7291 traplocs[trap_here.to_i()].push_back( pnt );
7292 }
7293 const ter_t &ter = tmpsub->get_ter( p ).obj();
7294 if( ter.trap != tr_null && ter.trap != tr_ledge ) {
7295 traplocs[ter.trap.to_i()].push_back( pnt );
7296 }
7297
7298 if( do_funnels ) {
7299 fill_funnels( pnt, tmpsub->last_touched );
7300 }
7301
7302 grow_plant( pnt );
7303
7304 restock_fruits( pnt, time_since_last_actualize );
7305
7306 produce_sap( pnt, time_since_last_actualize );
7307
7308 rad_scorch( pnt, time_since_last_actualize );
7309
7310 decay_cosmetic_fields( pnt, time_since_last_actualize );
7311 }
7312 }
7313
7314 // the last time we touched the submap, is right now.
7315 tmpsub->last_touched = calendar::turn;
7316}
const T & obj() const
Definition: ammo_effect.cpp:26
int to_i() const
Returns the identifier as plain int.
Definition: int_id.h:84
void remove_rotten_items(Container &items, const tripoint &p)
Go through the list of items, update their rotten status and remove items that have rotten away compl...
Definition: map.cpp:6947
void rad_scorch(const tripoint &p, const time_duration &time_since_last_actualize)
Radiation-related plant (and fungus?) death.
Definition: map.cpp:7198
void fill_funnels(const tripoint &p, const time_point &since)
Try to fill funnel based items here.
Definition: map.cpp:6986
std::vector< tripoint > field_furn_locs
Vector of tripoints containing active field-emitting furniture.
Definition: map.h:1973
void decay_cosmetic_fields(const tripoint &p, const time_duration &time_since_last_actualize)
Definition: map.cpp:7244
void restock_fruits(const tripoint &p, const time_duration &time_since_last_actualize)
Try to grow fruits on static plants (not planted by the player)
Definition: map.cpp:7087
ter_id ter(const tripoint &p) const
Definition: map.cpp:1493
void grow_plant(const tripoint &p)
Try to grow a harvestable plant to the next stage(s).
Definition: map.cpp:7009
submap * get_submap_at_grid(const point &gridp) const
Get submap pointer in the grid at given grid coordinates.
Definition: map.h:1840
void produce_sap(const tripoint &p, const time_duration &time_since_last_actualize)
Produce sap on tapped maple trees.
Definition: map.cpp:7101
furn_id furn(const tripoint &p) const
Definition: map.cpp:1343
Definition: submap.h:65
time_point last_touched
Definition: submap.h:240
trap_id get_trap(const point &p) const
Definition: submap.h:73
ter_id get_ter(const point &p) const
Definition: submap.h:99
cata::colony< item > & get_items(const point &p)
Definition: submap.h:161
A duration defined as a number of specific time units.
Definition: calendar.h:180
point sm_to_ms_copy(const point &p)
static constexpr int SEEX
static constexpr int SEEY
static const trap_str_id tr_ledge("tr_ledge")
time_point turn
Definition: calendar.cpp:36
Definition: point.h:35
Definition: mapdata.h:457
trap_id tr_null
Definition: trap.cpp:276

References debugmsg, decay_cosmetic_fields(), field_furn_locs, fill_funnels(), furn(), submap::get_items(), get_submap_at_grid(), submap::get_ter(), submap::get_trap(), grid, grow_plant(), submap::last_touched, int_id< T >::obj(), produce_sap(), rad_scorch(), remove_rotten_items(), restock_fruits(), SEEX, SEEY, sm_to_ms_copy(), ter(), int_id< T >::to_i(), tr_ledge, tr_null, traplocs, and calendar::turn.

Referenced by loadn().

◆ add_camp()

void map::add_camp ( const tripoint_abs_omt omt_pos,
const std::string &  name 
)

Definition at line 5557 of file map.cpp.

5558{
5559 basecamp temp_camp = basecamp( name, omt_pos );
5560 overmap_buffer.add_camp( temp_camp );
5561 g->u.camps.insert( omt_pos );
5562 g->validate_camps();
5563}
std::string name(const tripoint &p)
Definition: map.cpp:1320
void add_camp(const basecamp &camp)
Add Basecamp to overmapbuffer.
std::unique_ptr< game > g
Definition: game.cpp:267
overmapbuffer overmap_buffer

References overmapbuffer::add_camp(), g, name(), and overmap_buffer.

Referenced by get_basecamp().

◆ add_computer()

computer * map::add_computer ( const tripoint p,
const std::string &  name,
int  security 
)

Definition at line 5783 of file mapgen.cpp.

5784{
5785 // TODO: Turn this off?
5786 ter_set( p, t_console );
5787 point l;
5788 submap *const place_on_submap = get_submap_at( p, l );
5789 place_on_submap->set_computer( l, computer( name, security ) );
5790 return place_on_submap->get_computer( l );
5791}
bool ter_set(const tripoint &p, const ter_id &new_terrain)
Definition: map.cpp:1634
submap * get_submap_at(const tripoint &p) const
Get the submap pointer containing the specified position within the reality bubble.
Definition: map.cpp:8115
void set_computer(const point &p, const computer &c)
Definition: submap.cpp:203
const computer * get_computer(const point &p) const
Definition: submap.cpp:177
ter_id t_console
Definition: mapdata.cpp:704

References submap::get_computer(), get_submap_at(), name(), submap::set_computer(), t_console, and ter_set().

Referenced by jmapgen_computer::apply(), create_lab_consoles(), draw_lab(), mission_start::place_npc_software(), and science_room().

◆ add_corpse()

void map::add_corpse ( const tripoint p)

Definition at line 8259 of file map.cpp.

8260{
8261 item body;
8262
8263 const bool isReviveSpecial = one_in( 10 );
8264
8265 if( !isReviveSpecial ) {
8266 body = item::make_corpse();
8267 } else {
8268 body = item::make_corpse( mon_zombie );
8269 body.set_flag( "REVIVE_SPECIAL" );
8270 }
8271
8272 put_items_from_loc( item_group_id( "default_zombie_clothes" ), p );
8273 if( one_in( 3 ) ) {
8274 put_items_from_loc( item_group_id( "default_zombie_items" ), p );
8275 }
8276
8277 add_item_or_charges( p, body );
8278}
Definition: item.h:176
static item make_corpse(const mtype_id &mt=string_id< mtype >::NULL_ID(), time_point turn=calendar::turn, const std::string &name="", int upgrade_time=-1)
Make a corpse of the given monster type.
Definition: item.cpp:503
item & set_flag(const std::string &flag)
Idempotent filter setting an item specific flag.
Definition: item.cpp:5210
item & add_item_or_charges(const tripoint &pos, item obj, bool overflow=true)
Adds an item to map tile or stacks charges.
Definition: map.cpp:4214
std::vector< item * > put_items_from_loc(const item_group_id &loc, const tripoint &p, const time_point &turn=calendar::start_of_cataclysm)
Place items from an item group at p.
Definition: mapgen.cpp:5571
static const mtype_id mon_zombie("mon_zombie")
bool one_in(int chance)
Definition: rng.cpp:65
string_id< Item_group > item_group_id
Definition: type_id.h:70

References add_item_or_charges(), item::make_corpse(), mon_zombie, one_in(), put_items_from_loc(), and item::set_flag().

Referenced by add_corpse(), MapExtras::mx_looters(), MapExtras::mx_mayhem(), and MapExtras::mx_minefield().

◆ add_field()

bool map::add_field ( const tripoint p,
const field_type_id type_id,
int  intensity = INT_MAX,
const time_duration age = 0_turns,
bool  hit_player = true 
)

Add field entry at point, or set intensity if present.

Returns
false if the field could not be created (out of bounds), otherwise true.

Definition at line 5386 of file map.cpp.

5388{
5389 if( !inbounds( p ) ) {
5390 return false;
5391 }
5392
5393 if( !type_id ) {
5394 debugmsg( "Tried to add null field" );
5395 return false;
5396 }
5397
5398 const field_type &fd_type = *type_id;
5399 intensity = std::min( intensity, fd_type.get_max_intensity() );
5400 if( intensity <= 0 ) {
5401 return false;
5402 }
5403
5404 point l;
5405 submap *const current_submap = get_submap_at( p, l );
5406 current_submap->is_uniform = false;
5408
5409 if( current_submap->get_field( l ).add_field( type_id, intensity, age ) ) {
5410 //Only adding it to the count if it doesn't exist.
5411 if( !current_submap->field_count++ ) {
5412 get_cache( p.z ).field_cache.set( static_cast<size_t>( p.x / SEEX + ( (
5413 p.y / SEEX ) * MAPSIZE ) ) );
5414 }
5415 }
5416
5417 if( hit_player ) {
5418 Character &player_character = get_player_character();
5419 if( g != nullptr && this == &get_map() && p == player_character.pos() ) {
5420 //Hit the player with the field if it spawned on top of them.
5421 creature_in_field( player_character );
5422 }
5423 }
5424
5425 // Dirty the transparency cache now that field processing doesn't always do it
5426 if( fd_type.dirty_transparency_cache || !fd_type.is_transparent() ) {
5429 }
5430
5431 if( fd_type.is_dangerous() ) {
5433 }
5434
5435 // Ensure blood type fields don't hang in the air
5436 if( zlevels && fd_type.accelerated_decay ) {
5437 support_dirty( p );
5438 }
5439
5440 return true;
5441}
Character & get_player_character()
Definition: character.cpp:383
const tripoint & pos() const override
Definition: character.cpp:709
bool add_field(const field_type_id &field_type_to_add, int new_intensity=1, const time_duration &new_age=0_turns)
Inserts the given field_type_id into the field list for a given tile if it does not already exist.
Definition: field.cpp:190
void set_transparency_cache_dirty(const int zlev)
Sets a dirty flag on the a given cache.
Definition: map.h:393
level_cache & get_cache(int zlev) const
Definition: map.h:1997
virtual bool inbounds(const tripoint &p) const
Definition: map.cpp:7614
void set_pathfinding_cache_dirty(int zlev)
Definition: map.cpp:8575
void creature_in_field(Creature &critter)
Apply field effects to the creature when it's on a square with fields.
Definition: map_field.cpp:1560
void support_dirty(const tripoint &p)
Definition: map.cpp:2262
void invalidate_max_populated_zlev(int zlev)
Conditionally invalidates max_pupulated_zlev cache if the submap uniformity change occurs above curre...
Definition: map.cpp:8768
void set_seen_cache_dirty(const tripoint change_location)
Definition: map.h:409
int field_count
Definition: submap.h:239
field & get_field(const point &p)
Definition: submap.h:170
bool is_uniform
Definition: submap.h:233
map & get_map()
Definition: map.cpp:142
bool accelerated_decay
Definition: field_type.h:179
bool is_transparent() const
Definition: field_type.h:262
bool dirty_transparency_cache
Definition: field_type.h:161
bool is_dangerous() const
Definition: field_type.h:256
int get_max_intensity() const
Definition: field_type.h:268
std::bitset< MAPSIZE *MAPSIZE > field_cache
Definition: map.h:340
int y
Definition: point.h:151
int z
Definition: point.h:152
int x
Definition: point.h:150

References field_type::accelerated_decay, field::add_field(), creature_in_field(), debugmsg, field_type::dirty_transparency_cache, level_cache::field_cache, submap::field_count, g, get_cache(), submap::get_field(), get_map(), field_type::get_max_intensity(), get_player_character(), get_submap_at(), inbounds(), invalidate_max_populated_zlev(), field_type::is_dangerous(), field_type::is_transparent(), submap::is_uniform, MAPSIZE, Character::pos(), SEEX, set_pathfinding_cache_dirty(), set_seen_cache_dirty(), set_transparency_cache_dirty(), support_dirty(), tripoint::x, tripoint::y, tripoint::z, and zlevels.

Referenced by Character::activate_bionic(), jmapgen_field::apply(), apply_ammo_effects(), Character::blossoms(), start_location::burn(), create_anomaly(), spell::create_field(), create_hot_air(), explosion_handler::do_blast(), draw_lab(), draw_mine(), draw_temple(), draw_triffid(), drop_fields(), editmap::edit_fld(), iexamine::fireplace(), gas_spread_to(), hit_with_fire(), madd_field(), MapExtras::mx_casings(), MapExtras::mx_corpses(), MapExtras::mx_drugdeal(), MapExtras::mx_looters(), MapExtras::mx_mayhem(), MapExtras::mx_minefield(), MapExtras::mx_portal_in(), MapExtras::mx_roadblock(), MapExtras::mx_spider(), game::process_artifact(), process_fields_in_submap(), explosion_handler::explosion_funcs::resonance_cascade(), set_field_intensity(), shoot(), explosion_iuse::trigger_explosion(), and consume_drug_iuse::use().

◆ add_item() [1/2]

void map::add_item ( const point p,
item  new_item 
)
inline

Definition at line 1276 of file map.h.

1276 {
1277 add_item( tripoint( p, abs_sub.z ), new_item );
1278 }
tripoint abs_sub
Absolute coordinates of first submap (get_submap_at(0,0)) This is in submap coordinates (see overmapb...
Definition: map.h:1805
item & add_item(const tripoint &p, item new_item)
Place an item on the map, despite the parameter name, this is not necessarily a new item.
Definition: map.cpp:4314

References abs_sub, add_item(), and tripoint::z.

◆ add_item() [2/2]

item & map::add_item ( const tripoint p,
item  new_item 
)

Place an item on the map, despite the parameter name, this is not necessarily a new item.

WARNING: does -not- check volume or stack charges. player functions (drop etc) should use map::add_item_or_charges

Returns
The item that got added, or nulitem.

Definition at line 4314 of file map.cpp.

4315{
4316 if( !inbounds( p ) ) {
4317 return null_item_reference();
4318 }
4319 point l;
4320 submap *const current_submap = get_submap_at( p, l );
4321
4322 // Process foods when they are added to the map, here instead of add_item_at()
4323 // to avoid double processing food and corpses during active item processing.
4324 if( new_item.is_food() ) {
4325 new_item.process( nullptr, p, false );
4326 }
4327
4328 if( new_item.made_of( LIQUID ) && has_flag( "SWIMMABLE", p ) ) {
4329 return null_item_reference();
4330 }
4331
4332 if( has_flag( "DESTROY_ITEM", p ) ) {
4333 return null_item_reference();
4334 }
4335
4336 if( new_item.has_flag( "ACT_IN_FIRE" ) && get_field( p, fd_fire ) != nullptr ) {
4337 if( new_item.has_flag( "BOMB" ) && new_item.is_transformable() ) {
4338 //Convert a bomb item into its transformable version, e.g. incendiary grenade -> active incendiary grenade
4339 new_item.convert( dynamic_cast<const iuse_transform *>
4340 ( new_item.type->get_use( "transform" )->get_actor_ptr() )->target );
4341 }
4342 new_item.active = true;
4343 }
4344
4345 if( new_item.is_map() && !new_item.has_var( "reveal_map_center_omt" ) ) {
4346 new_item.set_var( "reveal_map_center_omt", ms_to_omt_copy( getabs( p ) ) );
4347 }
4348
4349 current_submap->is_uniform = false;
4351
4352 current_submap->update_lum_add( l, new_item );
4353
4354 const map_stack::iterator new_pos = current_submap->get_items( l ).insert( new_item );
4355 if( new_item.needs_processing() ) {
4356 if( current_submap->active_items.empty() ) {
4357 submaps_with_active_items.insert( tripoint( abs_sub.x + p.x / SEEX, abs_sub.y + p.y / SEEY, p.z ) );
4358 }
4359 current_submap->active_items.add( *new_pos, l );
4360 }
4361
4362 return *new_pos;
4363}
void add(item &it, point location)
Adds the reference to the cache.
bool empty() const
Returns true if the cache is empty.
bool is_transformable() const
Definition: item.cpp:6797
bool needs_processing() const
Whether the item should be processed (by calling process).
Definition: item.cpp:8761
bool active
Definition: item.h:2233
bool process(player *carrier, const tripoint &pos, bool activate, float insulation=1, temperature_flag flag=temperature_flag::TEMP_NORMAL)
This is called once each turn.
Definition: item.cpp:9415
const std::vector< material_id > & made_of() const
The ids of all the materials this is made of.
Definition: item.cpp:6252
item & convert(const itype_id &new_type)
Filter converting this instance to another type preserving all other aspects.
Definition: item.cpp:529
bool has_var(const std::string &name) const
Whether the variable is defined at all.
Definition: item.cpp:1066
void set_var(const std::string &name, int value)
Definition: item.cpp:991
bool has_flag(const std::string &flag) const
Definition: item.cpp:5181
bool is_map() const
Definition: item.cpp:6553
bool is_food() const
Definition: item.cpp:6431
const itype * type
Definition: item.h:2156
Transform an item into a specific type.
Definition: iuse_actor.h:52
itype_id target
type of the resulting item
Definition: iuse_actor.h:58
std::set< tripoint > submaps_with_active_items
Set of submaps that contain active items in absolute coordinates.
Definition: map.h:1983
field_entry * get_field(const tripoint &p, const field_type_id &type)
Get field of specific type at point.
Definition: map.cpp:5363
tripoint getabs(const tripoint &p) const
Translates local (to this map) coordinates of a square to global absolute coordinates.
Definition: map.cpp:8074
void update_lum_add(const point &p, const item &i)
Definition: submap.h:130
active_item_cache active_items
Definition: submap.h:237
point ms_to_omt_copy(const point &p)
@ LIQUID
Definition: enums.h:175
field_type_id fd_fire
Definition: field_type.cpp:345
item & null_item_reference()
Returns a reference to a null item (see item::is_null).
Definition: item.cpp:318
const use_function * get_use(const std::string &iuse_name) const
Definition: itype.cpp:91
iuse_actor * get_actor_ptr()
Definition: iuse.h:315

References abs_sub, item::active, submap::active_items, active_item_cache::add(), item::convert(), active_item_cache::empty(), fd_fire, use_function::get_actor_ptr(), get_field(), submap::get_items(), get_submap_at(), itype::get_use(), getabs(), item::has_flag(), has_flag(), item::has_var(), inbounds(), invalidate_max_populated_zlev(), item::is_food(), item::is_map(), item::is_transformable(), submap::is_uniform, LIQUID, item::made_of(), ms_to_omt_copy(), item::needs_processing(), null_item_reference(), item::process(), SEEX, SEEY, item::set_var(), submaps_with_active_items, iuse_transform::target, item::type, submap::update_lum_add(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by add_item(), add_item_or_charges(), iexamine::arcfurnace_empty(), iexamine::arcfurnace_full(), draw_mine(), extract_or_wreck_cbms(), iexamine::fvat_empty(), iexamine::fvat_full(), iexamine::keg(), iexamine::kiln_empty(), iexamine::kiln_full(), mill_activate(), mill_load_food(), Character::perform_uninstall(), place_gas_pump(), place_toilet(), iexamine::pour_into_keg(), iexamine::reload_furniture(), smoker_activate(), smoker_load_food(), Character::uninstall_bionic(), and game::wield().

◆ add_item_or_charges() [1/2]

item & map::add_item_or_charges ( const point p,
item  obj,
bool  overflow = true 
)
inline

Definition at line 1264 of file map.h.

1264 {
1265 return add_item_or_charges( tripoint( p, abs_sub.z ), obj, overflow );
1266 }

References abs_sub, add_item_or_charges(), and tripoint::z.

◆ add_item_or_charges() [2/2]

item & map::add_item_or_charges ( const tripoint pos,
item  obj,
bool  overflow = true 
)

Adds an item to map tile or stacks charges.

Parameters
posWhere to add item
objItem to add
overflowif destination is full attempt to drop on adjacent tiles
Returns
reference to dropped (and possibly stacked) item or null item on failure
Warning
function is relatively expensive and meant for user initiated actions, not mapgen

Definition at line 4214 of file map.cpp.

4215{
4216 // Checks if item would not be destroyed if added to this tile
4217 auto valid_tile = [&]( const tripoint & e ) {
4218 if( !inbounds( e ) ) {
4219 // should never happen
4220 debugmsg( "add_item_or_charges: %s is out of bounds (adding item '%s' [%d])",
4221 e.to_string(), obj.typeId().c_str(), obj.charges );
4222 return false;
4223 }
4224
4225 // Some tiles destroy items (e.g. lava)
4226 if( has_flag( "DESTROY_ITEM", e ) ) {
4227 return false;
4228 }
4229
4230 // Cannot drop liquids into tiles that are comprised of liquid
4231 if( obj.made_of( LIQUID ) && has_flag( "SWIMMABLE", e ) ) {
4232 return false;
4233 }
4234
4235 return true;
4236 };
4237
4238 // Checks if sufficient space at tile to add item
4239 auto valid_limits = [&]( const tripoint & e ) {
4240 return obj.volume() <= free_volume( e ) && i_at( e ).size() < MAX_ITEM_IN_SQUARE;
4241 };
4242
4243 // Performs the actual insertion of the object onto the map
4244 auto place_item = [&]( const tripoint & tile ) -> item& {
4245 if( obj.count_by_charges() )
4246 {
4247 for( auto &e : i_at( tile ) ) {
4248 if( e.merge_charges( obj ) ) {
4249 return e;
4250 }
4251 }
4252 }
4253
4254 support_dirty( tile );
4255 return add_item( tile, obj );
4256 };
4257
4258 // Some items never exist on map as a discrete item (must be contained by another item)
4259 if( obj.has_flag( "NO_DROP" ) ) {
4260 return null_item_reference();
4261 }
4262
4263 // If intended drop tile destroys the item then we don't attempt to overflow
4264 if( !valid_tile( pos ) ) {
4265 return null_item_reference();
4266 }
4267
4268 if( ( !has_flag( "NOITEM", pos ) || ( has_flag( "LIQUIDCONT", pos ) && obj.made_of( LIQUID ) ) )
4269 && valid_limits( pos ) ) {
4270 // Pass map into on_drop, because this map may not be the global map object (in mapgen, for instance).
4271 if( obj.made_of( LIQUID ) || !obj.has_flag( "DROP_ACTION_ONLY_IF_LIQUID" ) ) {
4272 if( obj.on_drop( pos, *this ) ) {
4273 return null_item_reference();
4274 }
4275
4276 }
4277 // If tile can contain items place here...
4278 return place_item( pos );
4279
4280 } else if( overflow ) {
4281 // ...otherwise try to overflow to adjacent tiles (if permitted)
4282 const int max_dist = 2;
4283 std::vector<tripoint> tiles = closest_points_first( pos, max_dist );
4284 tiles.erase( tiles.begin() ); // we already tried this position
4285 const int max_path_length = 4 * max_dist;
4286 const pathfinding_settings setting( 0, max_dist, max_path_length, 0, false, true, false, false,
4287 false );
4288 for( const tripoint &e : tiles ) {
4289 if( !inbounds( e ) ) {
4290 continue;
4291 }
4292 //must be a path to the target tile
4293 if( route( pos, e, setting ).empty() ) {
4294 continue;
4295 }
4296 if( obj.made_of( LIQUID ) || !obj.has_flag( "DROP_ACTION_ONLY_IF_LIQUID" ) ) {
4297 if( obj.on_drop( e, *this ) ) {
4298 return null_item_reference();
4299 }
4300 }
4301
4302 if( !valid_tile( e ) || !valid_limits( e ) ||
4303 has_flag( "NOITEM", e ) || has_flag( "SEALED", e ) ) {
4304 continue;
4305 }
4306 return place_item( e );
4307 }
4308 }
4309
4310 // failed due to lack of space at target tile (+/- overflow tiles)
4311 return null_item_reference();
4312}
size_t size() const
Definition: item_stack.cpp:10
bool count_by_charges() const
Definition: item.cpp:5844
units::volume volume(bool integral=false) const
Total volume of an item accounting for all contained/integrated items NOTE: Result is rounded up to n...
Definition: item.cpp:4980
int charges
Definition: item.h:2195
bool on_drop(const tripoint &pos)
Invokes item type's itype::drop_action.
Definition: item.cpp:9803
const itype_id & typeId() const
return the unique identifier of the items underlying type
Definition: item.cpp:8185
map_stack i_at(const tripoint &p)
Definition: map.cpp:4069
units::volume free_volume(const tripoint &p)
Definition: map.cpp:4209
std::vector< tripoint > route(const tripoint &f, const tripoint &t, const pathfinding_settings &settings, const std::set< tripoint > &pre_closed={{ }}) const
Calculate the best path using A*.
const char * c_str() const
Interface to the plain C-string of the id.
Definition: string_id.h:247
std::vector< coords::coord_point< Point, Origin, Scale > > closest_points_first(const coords::coord_point< Point, Origin, Scale > &loc, int min_dist, int max_dist)
Definition: coordinates.h:596
static constexpr int MAX_ITEM_IN_SQUARE

References add_item(), string_id< T >::c_str(), item::charges, closest_points_first(), item::count_by_charges(), debugmsg, free_volume(), item::has_flag(), has_flag(), i_at(), inbounds(), LIQUID, item::made_of(), MAX_ITEM_IN_SQUARE, null_item_reference(), item::on_drop(), wrapped_vehicle::pos, route(), item_stack::size(), support_dirty(), item::typeId(), and item::volume().

Referenced by Character::absorb_hit(), computer_session::action_conveyor(), computer_session::action_data_anal(), computer_session::action_sample(), Character::activate_bionic(), add_corpse(), add_item_or_charges(), MapgenRemovePartHandler::add_item_or_charges(), jmapgen_liquid_item::apply(), butchery_drops_harvest(), butchery_quarter(), defense_game::caravan(), game::catch_a_monster(), activity_handlers::chop_logs_finish(), doors::close_door(), talk_function::companion_return(), complete_construction(), iexamine::deployed_furniture(), game::disable_robot(), basecamp::distribute_food(), draw_lab(), Character::drop_invalid_inventory(), drop_items(), npc::drop_items(), drop_on_map(), drop_or_embed_projectile(), talk_function::drop_stolen_item(), talk_function::drop_weapon(), iexamine::elevator(), explosion_handler::emp_blast(), farm_action(), fetch_activity(), talk_function::field_plant(), activity_handlers::fill_liquid_do_turn(), iexamine::fireplace(), game::forced_door_closing(), fromPumpFuel(), iexamine::fvat_full(), iexamine::gaspump(), handle_harvest(), pickup::handle_spillable_contents(), iexamine::harvest_plant(), Character::i_add_or_drop(), map_stack::insert(), make_mon_corpse(), make_rubble(), mill_activate(), move_item(), MapExtras::mx_grave(), MapExtras::mx_mayhem(), MapExtras::mx_minefield(), iexamine::nanofab(), om_set_hide_site(), liquid_handler::perform_liquid_transfer(), iexamine::pit_covered(), Character::place_corpse(), basecamp::place_results(), activity_handlers::plant_seed_finish(), talk_function::player_weapon_drop(), iexamine::portable_structure(), process_fields_in_submap(), put_into_vehicle(), iexamine::quern_examine(), rcdrive(), rod_fish(), set_item_map(), activity_handlers::shear_finish(), smash_items(), smoker_activate(), iexamine::smoker_options(), spawn_an_item(), spawn_artifact(), spawn_items(), spawn_natural_artifact(), item_contents::spill_contents(), mdeath::splatter(), stash_on_pet(), iexamine::toPumpFuel(), iexamine::trap(), iexamine::tree_maple(), iexamine::tree_maple_tapped(), unroll_digging(), and unpack_actor::use().

◆ add_light_from_items()

void map::add_light_from_items ( const tripoint p,
item_stack::iterator  begin,
item_stack::iterator  end 
)
private

Definition at line 63 of file lightmap.cpp.

65{
66 for( auto itm_it = begin; itm_it != end; ++itm_it ) {
67 float ilum = 0.0f; // brightness
68 units::angle iwidth = 0_degrees; // 0-360 degrees. 0 is a circular light_source
69 units::angle idir = 0_degrees; // otherwise, it's a light_arc pointed in this direction
70 if( itm_it->getlight( ilum, iwidth, idir ) ) {
71 if( iwidth > 0_degrees ) {
72 apply_light_arc( p, idir, ilum, iwidth );
73 } else {
74 add_light_source( p, ilum );
75 }
76 }
77 }
78}
void apply_light_arc(const tripoint &p, units::angle, float luminance, units::angle wideangle=30_degrees)
Definition: lightmap.cpp:1478
void add_light_source(const tripoint &p, float luminance)
Definition: lightmap.cpp:582

References add_light_source(), and apply_light_arc().

Referenced by generate_lightmap().

◆ add_light_source()

void map::add_light_source ( const tripoint p,
float  luminance 
)
private

Definition at line 582 of file lightmap.cpp.

583{
584 auto &light_source_buffer = get_cache( p.z ).light_source_buffer;
585 light_source_buffer[p.x][p.y] = std::max( luminance, light_source_buffer[p.x][p.y] );
586}
float light_source_buffer[MAPSIZE_X][MAPSIZE_Y]
Definition: map.h:308

References get_cache(), level_cache::light_source_buffer, tripoint::x, tripoint::y, and tripoint::z.

Referenced by add_light_from_items(), and generate_lightmap().

◆ add_roofs()

void map::add_roofs ( const tripoint grid)
protected

Hacks in missing roofs.

Should be removed when 3D mapgen is done.

Definition at line 7318 of file map.cpp.

7319{
7320 if( !zlevels ) {
7321 // No roofs required!
7322 // Why not? Because submaps below and above don't exist yet
7323 return;
7324 }
7325
7326 submap *const sub_here = get_submap_at_grid( grid );
7327 if( sub_here == nullptr ) {
7328 debugmsg( "Tried to add roofs/floors on null submap on %d,%d,%d",
7329 grid.x, grid.y, grid.z );
7330 return;
7331 }
7332
7333 bool check_roof = grid.z > -OVERMAP_DEPTH;
7334
7335 submap *const sub_below = check_roof ? get_submap_at_grid( grid + tripoint_below ) : nullptr;
7336
7337 if( check_roof && sub_below == nullptr ) {
7338 debugmsg( "Tried to add roofs to sm at %d,%d,%d, but sm below doesn't exist",
7339 grid.x, grid.y, grid.z );
7340 return;
7341 }
7342
7343 for( int x = 0; x < SEEX; x++ ) {
7344 for( int y = 0; y < SEEY; y++ ) {
7345 const ter_id ter_here = sub_here->get_ter( { x, y } );
7346 if( ter_here != t_open_air ) {
7347 continue;
7348 }
7349
7350 if( !check_roof ) {
7351 // Make sure we don't have open air at lowest z-level
7352 sub_here->set_ter( { x, y }, t_rock_floor );
7353 continue;
7354 }
7355
7356 const ter_t &ter_below = sub_below->get_ter( { x, y } ).obj();
7357 if( ter_below.roof ) {
7358 // TODO: Make roof variable a ter_id to speed this up
7359 sub_here->set_ter( { x, y }, ter_below.roof.id() );
7360 }
7361 }
7362 }
7363}
int_id< T > id() const
Translate the string based it to the matching integer based id.
Definition: ammo_effect.cpp:54
void set_ter(const point &p, ter_id terr)
Definition: submap.h:103
ter_id t_open_air
Definition: mapdata.cpp:727
ter_id t_rock_floor
Definition: mapdata.cpp:627
static constexpr tripoint tripoint_below
Definition: point.h:295
ter_str_id roof
Definition: mapdata.h:464

References debugmsg, get_submap_at_grid(), submap::get_ter(), grid, string_id< T >::id(), OVERMAP_DEPTH, ter_t::roof, SEEX, SEEY, submap::set_ter(), t_open_air, t_rock_floor, tripoint_below, and zlevels.

Referenced by loadn().

◆ add_spawn()

void map::add_spawn ( const mtype_id type,
int  count,
const tripoint p,
bool  friendly = false,
int  faction_id = -1,
int  mission_id = -1,
const std::string &  name = "NONE" 
) const

Definition at line 5578 of file mapgen.cpp.

5580{
5581 if( p.x < 0 || p.x >= SEEX * my_MAPSIZE || p.y < 0 || p.y >= SEEY * my_MAPSIZE ) {
5582 debugmsg( "Bad add_spawn(%s, %d, %d, %d)", type.c_str(), count, p.x, p.y );
5583 return;
5584 }
5585 point offset;
5586 submap *place_on_submap = get_submap_at( p, offset );
5587
5588 if( !place_on_submap ) {
5589 debugmsg( "centadodecamonant doesn't exist in grid; within add_spawn(%s, %d, %d, %d, %d)",
5590 type.c_str(), count, p.x, p.y, p.z );
5591 return;
5592 }
5594 return;
5595 }
5596 spawn_point tmp( type, count, offset, faction_id, mission_id, friendly, name );
5597 place_on_submap->spawns.push_back( tmp );
5598}
static bool monster_is_blacklisted(const mtype_id &m)
Definition: mongroup.cpp:280
std::vector< spawn_point > spawns
Definition: submap.h:241
@ type
Definition: enums.h:75
constexpr size_t count()
Definition: fmtlib_core.h:1073

References detail::count(), debugmsg, friendly, get_submap_at(), MonsterGroupManager::monster_is_blacklisted(), my_MAPSIZE, name(), SEEX, SEEY, submap::spawns, type, tripoint::x, tripoint::y, and tripoint::z.

Referenced by jmapgen_monster::apply(), generate(), mission_start::kill_horde_master(), mapgen_ants_generic(), mapgen_ants_larvae(), mapgen_ants_queen(), mapgen_hive(), mapgen_road(), MapExtras::mx_collegekids(), MapExtras::mx_drugdeal(), MapExtras::mx_helicopter(), MapExtras::mx_house_spider(), MapExtras::mx_house_wasp(), MapExtras::mx_jabberwock(), MapExtras::mx_marloss_pilgrimage(), MapExtras::mx_military(), MapExtras::mx_roadblock(), MapExtras::mx_science(), MapExtras::mx_shia(), MapExtras::mx_spider(), mission_start::place_dog(), place_spawns(), mission_start::place_zombie_mom(), process_fields_in_submap(), and rotten_item_spawn().

◆ add_splash()

void map::add_splash ( const field_type_id type,
const tripoint center,
int  radius,
int  intensity 
)

Definition at line 5506 of file map.cpp.

5508{
5509 if( !type.id() ) {
5510 return;
5511 }
5512 // TODO: use Bresenham here and take obstacles into account
5513 for( const tripoint &pnt : points_in_radius( center, radius ) ) {
5514 if( trig_dist( pnt, center ) <= radius && !one_in( intensity ) ) {
5515 add_splatter( type, pnt );
5516 }
5517 }
5518}
tripoint_range< tripoint > points_in_radius(const tripoint &center, size_t radius, size_t radiusz=0) const
Definition: map.cpp:8422
void add_splatter(const field_type_id &type, const tripoint &where, int intensity=1)
Definition: map.cpp:5469
int trig_dist(const coords::coord_point< Point, Origin, Scale > &loc1, const coords::coord_point< Point, Origin, Scale > &loc2)
Definition: coordinates.h:512

References add_splatter(), center, one_in(), points_in_radius(), trig_dist(), and type.

Referenced by smash_items().

◆ add_splatter()

void map::add_splatter ( const field_type_id type,
const tripoint where,
int  intensity = 1 
)

Definition at line 5469 of file map.cpp.

5470{
5471 if( intensity <= 0 ) {
5472 return;
5473 }
5474 if( type.obj().is_splattering ) {
5475 if( const optional_vpart_position vp = veh_at( where ) ) {
5476 vehicle *const veh = &vp->vehicle();
5477 // Might be -1 if all the vehicle's parts at where are marked for removal
5478 const int part = veh->part_displayed_at( vp->mount() );
5479 if( part != -1 ) {
5480 veh->part( part ).blood += 200 * std::min( intensity, 3 ) / 3;
5481 return;
5482 }
5483 }
5484 }
5485 mod_field_intensity( where, type, intensity );
5486}
optional_vpart_position veh_at(const tripoint &p) const
Checks if tile is occupied by vehicle and by which part.
Definition: map.cpp:1004
int mod_field_intensity(const tripoint &p, const field_type_id &type, int offset)
Increment/decrement intensity of field entry at point, creating if not present, removing if intensity...
Definition: map.cpp:5312
Simple wrapper to forward functions that may return a cata::optional to vpart_position.
A vehicle as a whole with all its components.
Definition: vehicle.h:675
vehicle(const vproto_id &type_id, int init_veh_fuel=-1, int init_veh_status=-1)
Definition: vehicle.cpp:251
vehicle_part & part(int part_num)
Definition: vehicle.cpp:6903
int part_displayed_at(const point &dp) const
Returns which part (as an index into the parts list) is the one that will be displayed for the given ...
Definition: vehicle.cpp:2936
int blood
how much blood covers part (in turns).
Definition: vehicle.h:398

References vehicle_part::blood, mod_field_intensity(), vehicle::part(), vehicle::part_displayed_at(), type, veh_at(), and vehicle::vehicle().

Referenced by add_splash(), add_splatter_trail(), Creature::bleed(), activity_handlers::butcher_finish(), and mdeath::splatter().

◆ add_splatter_trail()

void map::add_splatter_trail ( const field_type_id type,
const tripoint from,
const tripoint to 
)

Definition at line 5488 of file map.cpp.

5490{
5491 if( !type.id() ) {
5492 return;
5493 }
5494 const auto trail = line_to( from, to );
5495 int remainder = trail.size();
5496 for( const auto &elem : trail ) {
5497 add_splatter( type, elem );
5498 remainder--;
5499 if( impassable( elem ) ) { // Blood splatters stop at walls.
5500 add_splatter( type, elem, remainder );
5501 return;
5502 }
5503 }
5504}
bool impassable(const tripoint &p) const
Definition: map.cpp:1790
std::vector< coords::coord_point< Point, Origin, Scale > > line_to(const coords::coord_point< Point, Origin, Scale > &loc1, const coords::coord_point< Point, Origin, Scale > &loc2)
Definition: coordinates.h:548

References add_splatter(), impassable(), line_to(), and type.

Referenced by activity_handlers::butcher_finish(), MapExtras::mx_casings(), MapExtras::mx_mayhem(), MapExtras::mx_minefield(), projectile_attack(), and activity_handlers::pulp_do_turn().

◆ add_vehicle() [1/4]

vehicle * map::add_vehicle ( const vgroup_id type,
const point p,
units::angle  dir,
int  init_veh_fuel = -1,
int  init_veh_status = -1,
bool  merge_wrecks = true 
)

Definition at line 5606 of file mapgen.cpp.

5608{
5609 return add_vehicle( type.obj().pick(), p, dir, veh_fuel, veh_status, merge_wrecks );
5610}
vehicle * add_vehicle(const vgroup_id &type, const tripoint &p, units::angle dir, int init_veh_fuel=-1, int init_veh_status=-1, bool merge_wrecks=true)
Definition: mapgen.cpp:5600

References add_vehicle(), and type.

◆ add_vehicle() [2/4]

◆ add_vehicle() [3/4]

vehicle * map::add_vehicle ( const vproto_id type,
const point p,
units::angle  dir,
int  init_veh_fuel = -1,
int  init_veh_status = -1,
bool  merge_wrecks = true 
)

Definition at line 5612 of file mapgen.cpp.

5614{
5615 return add_vehicle( type, tripoint( p, abs_sub.z ), dir, veh_fuel, veh_status, merge_wrecks );
5616}

References abs_sub, add_vehicle(), type, and tripoint::z.

◆ add_vehicle() [4/4]

vehicle * map::add_vehicle ( const vproto_id type,
const tripoint p,
units::angle  dir,
int  init_veh_fuel = -1,
int  init_veh_status = -1,
bool  merge_wrecks = true 
)

Definition at line 5618 of file mapgen.cpp.

5620{
5621 if( !type.is_valid() ) {
5622 debugmsg( "Nonexistent vehicle type: \"%s\"", type.c_str() );
5623 return nullptr;
5624 }
5625 if( !inbounds( p ) ) {
5626 dbg( DL::Warn ) << string_format( "Out of bounds add_vehicle t=%s d=%d p=%s",
5627 type, to_degrees( dir ), p.to_string() );
5628 return nullptr;
5629 }
5630
5631 // debugmsg("n=%d x=%d y=%d MAPSIZE=%d ^2=%d", nonant, x, y, MAPSIZE, MAPSIZE*MAPSIZE);
5632 auto veh = std::make_unique<vehicle>( type, veh_fuel, veh_status );
5633 tripoint p_ms = p;
5634 veh->sm_pos = ms_to_sm_remain( p_ms );
5635 veh->pos = p_ms.xy();
5636 veh->place_spawn_items();
5637 // for backwards compatibility, we always spawn with a pivot point of (0,0) so
5638 // that the mount at (0,0) is located at the spawn position.
5639 veh->set_facing_and_pivot( dir, point_zero, false );
5640 //debugmsg("adding veh: %d, sm: %d,%d,%d, pos: %d, %d", veh, veh->smx, veh->smy, veh->smz, veh->posx, veh->posy);
5641 std::unique_ptr<vehicle> placed_vehicle_up =
5642 add_vehicle_to_map( std::move( veh ), merge_wrecks );
5643 vehicle *placed_vehicle = placed_vehicle_up.get();
5644
5645 if( placed_vehicle != nullptr ) {
5646 submap *place_on_submap = get_submap_at_grid( placed_vehicle->sm_pos );
5647 place_on_submap->vehicles.push_back( std::move( placed_vehicle_up ) );
5648 place_on_submap->is_uniform = false;
5650
5651 auto &ch = get_cache( placed_vehicle->sm_pos.z );
5652 ch.vehicle_list.insert( placed_vehicle );
5653 add_vehicle_to_cache( placed_vehicle );
5654
5655 //debugmsg ("grid[%d]->vehicles.size=%d veh.parts.size=%d", nonant, grid[nonant]->vehicles.size(),veh.parts.size());
5656 }
5657 return placed_vehicle;
5658}
std::unique_ptr< vehicle > add_vehicle_to_map(std::unique_ptr< vehicle > veh, bool merge_wrecks)
Takes a vehicle already created with new and attempts to place it on the map, checking for collisions...
Definition: mapgen.cpp:5669
void add_vehicle_to_cache(vehicle *)
Definition: map.cpp:267
std::vector< std::unique_ptr< vehicle > > vehicles
Vehicles on this submap (their (0,0) point is on this submap).
Definition: submap.h:247
tripoint sm_pos
Submap coordinates of the currently loaded submap (see game::m) that contains this vehicle.
Definition: vehicle.h:1881
point ms_to_sm_remain(int &x, int &y)
@ Warn
Warning (default: enabled).
#define dbg(x)
Definition: mapgen.cpp:97
bool move(avatar &you, map &m, const tripoint &d)
constexpr double to_degrees(const units::angle v)
Definition: units_angle.h:36
static constexpr point point_zero
Definition: point.h:274
std::string string_format(std::string format, Args &&...args)
Simple wrapper over string_formatter::parse.
constexpr point xy() const
Definition: point.h:220
std::string to_string() const
Definition: point.cpp:16

References add_vehicle_to_cache(), add_vehicle_to_map(), dbg, debugmsg, get_cache(), get_submap_at_grid(), inbounds(), invalidate_max_populated_zlev(), submap::is_uniform, avatar_action::move(), ms_to_sm_remain(), point_zero, vehicle::sm_pos, string_format(), units::to_degrees(), tripoint::to_string(), type, submap::vehicles, Warn, tripoint::xy(), and tripoint::z.

◆ add_vehicle_to_cache()

void map::add_vehicle_to_cache ( vehicle veh)

Definition at line 267 of file map.cpp.

268{
269 if( veh == nullptr ) {
270 debugmsg( "Tried to add null vehicle to cache" );
271 return;
272 }
273
274 // Get parts
275 for( const vpart_reference &vpr : veh->get_all_parts() ) {
276 if( vpr.part().removed ) {
277 continue;
278 }
279 const tripoint p = veh->global_part_pos3( vpr.part() );
280 level_cache &ch = get_cache( p.z );
281 ch.veh_in_active_range = true;
282 ch.veh_cached_parts[p] = std::make_pair( veh, static_cast<int>( vpr.part_index() ) );
283 if( inbounds( p ) ) {
284 ch.veh_exists_at[p.x][p.y] = true;
285 }
286 }
287
289}
bool last_full_vehicle_list_dirty
Definition: map.h:1994
vehicle_part_range get_all_parts() const
Yields a range containing all parts (including broken ones) that can be iterated over.
Definition: vehicle.cpp:6893
tripoint global_part_pos3(const int &index) const
Get the coordinates of the studied part of the vehicle.
Definition: vehicle.cpp:3109
This is a wrapper over a vehicle pointer and a reference to a part of it.
bool veh_in_active_range
Definition: map.h:342
bool veh_exists_at[MAPSIZE_X][MAPSIZE_Y]
Definition: map.h:343
std::map< tripoint, std::pair< vehicle *, int > > veh_cached_parts
Definition: map.h:344

References debugmsg, vehicle::get_all_parts(), get_cache(), vehicle::global_part_pos3(), inbounds(), last_full_vehicle_list_dirty, level_cache::veh_cached_parts, level_cache::veh_exists_at, level_cache::veh_in_active_range, tripoint::x, tripoint::y, and tripoint::z.

Referenced by add_vehicle(), veh_interact::complete_vehicle(), displace_vehicle(), construct::done_vehicle(), loadn(), vehicle::part_removal_cleanup(), and reset_vehicle_cache().

◆ add_vehicle_to_map()

std::unique_ptr< vehicle > map::add_vehicle_to_map ( std::unique_ptr< vehicle veh,
bool  merge_wrecks 
)
private

Takes a vehicle already created with new and attempts to place it on the map, checking for collisions.

If the vehicle can't be placed, returns NULL, otherwise returns a pointer to the placed vehicle, which may not necessarily be the one passed in (if wreckage is created by fusing cars).

Parameters
vehThe vehicle to place on the map.
merge_wrecksWhether crashed vehicles become part of each other
Returns
The vehicle that was finally placed.

Definition at line 5669 of file mapgen.cpp.

5671{
5672 //We only want to check once per square, so loop over all structural parts
5673 std::vector<int> frame_indices = veh->all_parts_at_location( "structure" );
5674
5675 //Check for boat type vehicles that should be placeable in deep water
5676 const bool can_float = size( veh->get_avail_parts( "FLOATS" ) ) > 2;
5677
5678 //When hitting a wall, only smash the vehicle once (but walls many times)
5679 bool needs_smashing = false;
5680
5681 veh->attach();
5682 veh->refresh_position();
5683
5684 for( std::vector<int>::const_iterator part = frame_indices.begin();
5685 part != frame_indices.end(); part++ ) {
5686 const auto p = veh->global_part_pos3( *part );
5687
5688 //Don't spawn anything in water
5689 if( has_flag_ter( TFLAG_DEEP_WATER, p ) && !can_float ) {
5690 return nullptr;
5691 }
5692
5693 // Don't spawn shopping carts on top of another vehicle or other obstacle.
5694 if( veh->type == vproto_id( "shopping_cart" ) ) {
5695 if( veh_at( p ) || impassable( p ) ) {
5696 return nullptr;
5697 }
5698 }
5699
5700 //For other vehicles, simulate collisions with (non-shopping cart) stuff
5701 vehicle *const other_veh = veh_pointer_or_null( veh_at( p ) );
5702 if( other_veh != nullptr && other_veh->type != vproto_id( "shopping_cart" ) ) {
5703 if( !merge_wrecks ) {
5704 return nullptr;
5705 }
5706
5707 // Hard wreck-merging limit: 200 tiles
5708 // Merging is slow for big vehicles which lags the mapgen
5709 if( frame_indices.size() + other_veh->all_parts_at_location( "structure" ).size() > 200 ) {
5710 return nullptr;
5711 }
5712
5713 /* There's a vehicle here, so let's fuse them together into wreckage and
5714 * smash them up. It'll look like a nasty collision has occurred.
5715 * Trying to do a local->global->local conversion would be a major
5716 * headache, so instead, let's make another vehicle whose (0, 0) point
5717 * is the (0, 0) of the existing vehicle, convert the coordinates of both
5718 * vehicles into global coordinates, find the distance between them and
5719 * p and then install them that way.
5720 * Create a vehicle with type "null" so it starts out empty. */
5721 auto wreckage = std::make_unique<vehicle>();
5722 wreckage->pos = other_veh->pos;
5723 wreckage->sm_pos = other_veh->sm_pos;
5724
5725 //Where are we on the global scale?
5726 const tripoint global_pos = wreckage->global_pos3();
5727
5728 for( const vpart_reference &vpr : veh->get_all_parts() ) {
5729 const tripoint part_pos = veh->global_part_pos3( vpr.part() ) - global_pos;
5730 // TODO: change mount points to be tripoint
5731 wreckage->install_part( part_pos.xy(), vpr.part() );
5732 }
5733
5734 for( const vpart_reference &vpr : other_veh->get_all_parts() ) {
5735 const tripoint part_pos = other_veh->global_part_pos3( vpr.part() ) - global_pos;
5736 wreckage->install_part( part_pos.xy(), vpr.part() );
5737
5738 }
5739
5740 wreckage->name = _( "Wreckage" );
5741
5742 // Now get rid of the old vehicles
5743 std::unique_ptr<vehicle> old_veh = detach_vehicle( other_veh );
5744 // Failure has happened here when caches are corrupted due to bugs.
5745 // Add an assertion to avoid null-pointer dereference later.
5746 assert( old_veh );
5747
5748 // Try again with the wreckage
5749 std::unique_ptr<vehicle> new_veh = add_vehicle_to_map( std::move( wreckage ), true );
5750 if( new_veh != nullptr ) {
5751 new_veh->smash( *this );
5752 return new_veh;
5753 }
5754
5755 // If adding the wreck failed, we want to restore the vehicle we tried to merge with
5756 add_vehicle_to_map( std::move( old_veh ), false );
5757 return nullptr;
5758
5759 } else if( impassable( p ) ) {
5760 if( !merge_wrecks ) {
5761 return nullptr;
5762 }
5763
5764 // There's a wall or other obstacle here; destroy it
5765 destroy( p, true );
5766
5767 // Some weird terrain, don't place the vehicle
5768 if( impassable( p ) ) {
5769 return nullptr;
5770 }
5771
5772 needs_smashing = true;
5773 }
5774 }
5775
5776 if( needs_smashing ) {
5777 veh->smash( *this );
5778 }
5779
5780 return veh;
5781}
void destroy(const tripoint &p, bool silent=false)
Keeps bashing a square until it can't be bashed anymore.
Definition: map.cpp:3617
std::unique_ptr< vehicle > detach_vehicle(vehicle *veh)
Definition: map.cpp:350
bool has_flag_ter(const std::string &flag, const tripoint &p) const
Definition: map.cpp:2307
point pos
Position of the vehicle inside the submap that contains the vehicle.
Definition: vehicle.h:1896
vproto_id type
Type of the vehicle as it was spawned.
Definition: vehicle.h:1835
std::vector< int > all_parts_at_location(const std::string &location) const
Returns all parts in the vehicle that exist in the given location slot.
Definition: vehicle.cpp:2747
@ TFLAG_DEEP_WATER
Definition: mapdata.h:301
const size_t size
Definition: om_direction.h:27
#define _(msg)
Definition: translations.h:116
vehicle * veh_pointer_or_null(const optional_vpart_position &p)

References _, add_vehicle_to_map(), vehicle::all_parts_at_location(), destroy(), detach_vehicle(), vehicle::get_all_parts(), vehicle::global_part_pos3(), has_flag_ter(), impassable(), avatar_action::move(), vehicle::pos, om_direction::size, vehicle::sm_pos, TFLAG_DEEP_WATER, vehicle::type, veh_at(), veh_pointer_or_null(), and tripoint::xy().

Referenced by add_vehicle(), and add_vehicle_to_map().

◆ adjust_radiation() [1/2]

void map::adjust_radiation ( const point p,
const int  delta 
)
inline

Definition at line 1192 of file map.h.

1192 {
1193 adjust_radiation( tripoint( p, abs_sub.z ), delta );
1194 }
void adjust_radiation(const tripoint &p, int delta)
Increment the radiation in the given tile by the given delta (decrement it if delta is negative)
Definition: map.cpp:4037

References abs_sub, adjust_radiation(), and tripoint::z.

◆ adjust_radiation() [2/2]

void map::adjust_radiation ( const tripoint p,
int  delta 
)

Increment the radiation in the given tile by the given delta (decrement it if delta is negative)

Definition at line 4037 of file map.cpp.

4038{
4039 if( !inbounds( p ) ) {
4040 return;
4041 }
4042
4043 point l;
4044 submap *const current_submap = get_submap_at( p, l );
4045
4046 int current_radiation = current_submap->get_radiation( l );
4047 current_submap->set_radiation( l, current_radiation + delta );
4048}
void set_radiation(const point &p, const int radiation)
Definition: submap.h:116
int get_radiation(const point &p) const
Definition: submap.h:112

References submap::get_radiation(), get_submap_at(), inbounds(), and submap::set_radiation().

Referenced by computer_session::action_irradiator(), adjust_radiation(), MapExtras::mx_crater(), MapExtras::mx_portal_in(), and process_fields_in_submap().

◆ ambient_light_at()

float map::ambient_light_at ( const tripoint p) const

Definition at line 615 of file lightmap.cpp.

616{
617 if( !inbounds( p ) ) {
618 return 0.0f;
619 }
620
621 return get_cache_ref( p.z ).lm[p.x][p.y].max();
622}
const level_cache & get_cache_ref(int zlev) const
Definition: map.h:2010
float max() const
Definition: shadowcasting.h:44
four_quadrants lm[MAPSIZE_X][MAPSIZE_Y]
Definition: map.h:304

References get_cache_ref(), inbounds(), level_cache::lm, four_quadrants::max(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by apply_character_light(), game::print_terrain_info(), and Creature::sees().

◆ apparent_light_at()

lit_level map::apparent_light_at ( const tripoint p,
const visibility_variables cache 
) const

Determine the visible light level for a tile, based on light_at for the tile, vision distance, etc.

Parameters
pThe tile on this map to draw.
cacheCurrently cached visibility parameters

Definition at line 698 of file lightmap.cpp.

699{
700 const int dist = rl_dist( g->u.pos(), p );
701
702 // Clairvoyance overrides everything.
703 if( dist <= cache.u_clairvoyance ) {
704 return lit_level::BRIGHT;
705 }
706 const auto &map_cache = get_cache_ref( p.z );
707 const apparent_light_info a = apparent_light_helper( map_cache, p );
708
709 // Unimpaired range is an override to strictly limit vision range based on various conditions,
710 // but the player can still see light sources.
711 if( dist > g->u.unimpaired_range() ) {
712 if( !a.obstructed && map_cache.sm[p.x][p.y] > 0.0 ) {
714 } else {
715 return lit_level::DARK;
716 }
717 }
718 if( a.obstructed ) {
719 if( a.apparent_light > LIGHT_AMBIENT_LIT ) {
720 if( a.apparent_light > cache.g_light_level ) {
721 // This represents too hazy to see detail,
722 // but enough light getting through to illuminate.
724 } else {
725 // If it's not brighter than the surroundings, it just ends up shadowy.
726 return lit_level::LOW;
727 }
728 } else {
729 return lit_level::BLANK;
730 }
731 }
732 // Then we just search for the light level in descending order.
733 if( a.apparent_light > LIGHT_SOURCE_BRIGHT || map_cache.sm[p.x][p.y] > 0.0 ) {
734 return lit_level::BRIGHT;
735 }
736 if( a.apparent_light > LIGHT_AMBIENT_LIT ) {
737 return lit_level::LIT;
738 }
739 if( a.apparent_light >= cache.vision_threshold ) {
740 return lit_level::LOW;
741 } else {
742 return lit_level::BLANK;
743 }
744}
static apparent_light_info apparent_light_helper(const level_cache &map_cache, const tripoint &p)
Helper function for light claculation; exposed here for map editor.
Definition: lightmap.cpp:636
int rl_dist(const coords::coord_point< Point, Origin, Scale > &loc1, const coords::coord_point< Point, Origin, Scale > &loc2)
Definition: coordinates.h:519
static constexpr float LIGHT_SOURCE_BRIGHT
Definition: lightmap.h:9
static constexpr float LIGHT_AMBIENT_LIT
Definition: lightmap.h:18
constexpr double a
Definition: magic.cpp:1030
float vision_threshold
Definition: map.h:124
int u_clairvoyance
Definition: map.h:123

References a, apparent_light_helper(), BLANK, BRIGHT, BRIGHT_ONLY, DARK, g, visibility_variables::g_light_level, get_cache_ref(), LIGHT_AMBIENT_LIT, LIGHT_SOURCE_BRIGHT, LIT, LOW, rl_dist(), visibility_variables::u_clairvoyance, visibility_variables::vision_threshold, tripoint::x, tripoint::y, and tripoint::z.

Referenced by game::draw_look_around_cursor(), game::print_all_tile_info(), editmap::update_view_with_help(), and update_visibility_cache().

◆ apparent_light_helper()

map::apparent_light_info map::apparent_light_helper ( const level_cache map_cache,
const tripoint p 
)
static

Helper function for light claculation; exposed here for map editor.

Definition at line 636 of file lightmap.cpp.

638{
639 const float vis = std::max( map_cache.seen_cache[p.x][p.y], map_cache.camera_cache[p.x][p.y] );
640 const bool obstructed = vis <= LIGHT_TRANSPARENCY_SOLID + 0.1;
641
642 auto is_opaque = [&map_cache]( const point & p ) {
643 return map_cache.transparency_cache[p.x][p.y] <= LIGHT_TRANSPARENCY_SOLID &&
645 };
646
647 const bool p_opaque = is_opaque( p.xy() );
648 float apparent_light;
649
650 if( p_opaque && vis > 0 ) {
651 // This is the complicated case. We want to check which quadrants the
652 // player can see the tile from, and only count light values from those
653 // quadrants.
654 struct offset_and_quadrants {
655 point offset;
656 std::array<quadrant, 2> quadrants;
657 };
658 static constexpr std::array<offset_and_quadrants, 8> adjacent_offsets = {{
667 }
668 };
669
670 four_quadrants seen_from( 0 );
671 for( const offset_and_quadrants &oq : adjacent_offsets ) {
672 const point neighbour = p.xy() + oq.offset;
673
674 if( !lightmap_boundaries.contains( neighbour ) ) {
675 continue;
676 }
677 if( is_opaque( neighbour ) ) {
678 continue;
679 }
680 if( map_cache.seen_cache[neighbour.x][neighbour.y] == 0 &&
681 map_cache.camera_cache[neighbour.x][neighbour.y] == 0 ) {
682 continue;
683 }
684 // This is a non-opaque visible neighbour, so count visibility from the relevant
685 // quadrants
686 seen_from[oq.quadrants[0]] = vis;
687 seen_from[oq.quadrants[1]] = vis;
688 }
689 apparent_light = ( seen_from * map_cache.lm[p.x][p.y] ).max();
690 } else {
691 // This is the simple case, for a non-opaque tile light from all
692 // directions is equivalent
693 apparent_light = vis * map_cache.lm[p.x][p.y].max();
694 }
695 return { obstructed, apparent_light };
696}
const half_open_rectangle< point > lightmap_boundaries(lightmap_boundary_min, lightmap_boundary_max)
static constexpr float LIGHT_TRANSPARENCY_SOLID
Transparency 101: Transparency usually ranges between 0.038 (open air) and 0.38 (regular smoke).
Definition: lightmap.h:32
static constexpr point point_south_west
Definition: point.h:281
static constexpr point point_west
Definition: point.h:282
static constexpr point point_north_east
Definition: point.h:277
static constexpr point point_north_west
Definition: point.h:283
static constexpr point point_south_east
Definition: point.h:279
static constexpr point point_south
Definition: point.h:280
static constexpr point point_north
Definition: point.h:276
static constexpr point point_east
Definition: point.h:278
float seen_cache[MAPSIZE_X][MAPSIZE_Y]
Definition: map.h:331
float transparency_cache[MAPSIZE_X][MAPSIZE_Y]
Definition: map.h:322
float vision_transparency_cache[MAPSIZE_X][MAPSIZE_Y]
Definition: map.h:327
float camera_cache[MAPSIZE_X][MAPSIZE_Y]
Definition: map.h:335
int y
Definition: point.h:39
int x
Definition: point.h:38

References level_cache::camera_cache, LIGHT_TRANSPARENCY_SOLID, lightmap_boundaries, level_cache::lm, four_quadrants::max(), NE, NW, point_east, point_north, point_north_east, point_north_west, point_south, point_south_east, point_south_west, point_west, SE, level_cache::seen_cache, SW, level_cache::transparency_cache, level_cache::vision_transparency_cache, point::x, tripoint::x, tripoint::xy(), point::y, and tripoint::y.

Referenced by apparent_light_at(), pl_sees(), and editmap::update_view_with_help().

◆ apply_character_light()

void map::apply_character_light ( Character p)
protected

Definition at line 196 of file lightmap.cpp.

197{
198 if( p.has_effect( effect_onfire ) ) {
199 apply_light_source( p.pos(), 8 );
200 } else if( p.has_effect( effect_haslight ) ) {
201 apply_light_source( p.pos(), 4 );
202 }
203
204 const float held_luminance = p.active_light();
205 if( held_luminance > LIGHT_AMBIENT_LOW ) {
206 apply_light_source( p.pos(), held_luminance );
207 }
208
209 if( held_luminance >= 4 && held_luminance > ambient_light_at( p.pos() ) - 0.5f ) {
210 p.add_effect( effect_haslight, 1_turns );
211 }
212}
float active_light() const
Returns character luminosity based on the brightest active item they are carrying.
Definition: character.cpp:6388
void add_effect(const effect &eff, bool force=false, bool deferred=false)
Definition: creature.cpp:977
bool has_effect(const efftype_id &eff_id, body_part bp=num_bp) const
Check if creature has the matching effect.
Definition: creature.cpp:1176
void apply_light_source(const tripoint &p, float luminance)
Definition: lightmap.cpp:1359
float ambient_light_at(const tripoint &p) const
Definition: lightmap.cpp:615
static const efftype_id effect_haslight("haslight")
static const efftype_id effect_onfire("onfire")
static constexpr float LIGHT_AMBIENT_LOW
Definition: lightmap.h:14

References Character::active_light(), Creature::add_effect(), ambient_light_at(), apply_light_source(), effect_haslight, effect_onfire, Creature::has_effect(), LIGHT_AMBIENT_LOW, and Character::pos().

Referenced by generate_lightmap().

◆ apply_directional_light()

void map::apply_directional_light ( const tripoint p,
int  direction,
float  luminance 
)
private

Definition at line 1439 of file lightmap.cpp.

1440{
1441 const point p2( p.xy() );
1442
1443 auto &cache = get_cache( p.z );
1444 four_quadrants( &lm )[MAPSIZE_X][MAPSIZE_Y] = cache.lm;
1445 float ( &transparency_cache )[MAPSIZE_X][MAPSIZE_Y] = cache.transparency_cache;
1446
1447 if( direction == 90 ) {
1448 castLight < 1, 0, 0, -1, float, four_quadrants, light_calc, light_check,
1450 lm, transparency_cache, p2, 0, luminance );
1451 castLight < -1, 0, 0, -1, float, four_quadrants, light_calc, light_check,
1453 lm, transparency_cache, p2, 0, luminance );
1454 } else if( direction == 0 ) {
1455 castLight < 0, -1, 1, 0, float, four_quadrants, light_calc, light_check,
1457 lm, transparency_cache, p2, 0, luminance );
1458 castLight < 0, -1, -1, 0, float, four_quadrants, light_calc, light_check,
1460 lm, transparency_cache, p2, 0, luminance );
1461 } else if( direction == 270 ) {
1462 castLight<1, 0, 0, 1, float, four_quadrants, light_calc, light_check,
1464 lm, transparency_cache, p2, 0, luminance );
1465 castLight < -1, 0, 0, 1, float, four_quadrants, light_calc, light_check,
1467 lm, transparency_cache, p2, 0, luminance );
1468 } else if( direction == 180 ) {
1469 castLight<0, 1, 1, 0, float, four_quadrants, light_calc, light_check,
1471 lm, transparency_cache, p2, 0, luminance );
1472 castLight < 0, 1, -1, 0, float, four_quadrants, light_calc, light_check,
1474 lm, transparency_cache, p2, 0, luminance );
1475 }
1476}
static constexpr int MAPSIZE_Y
static constexpr int MAPSIZE_X
static bool light_check(const float &transparency, const float &intensity)
Definition: lightmap.cpp:1354
static float light_calc(const float &numerator, const float &transparency, const int &distance)
Definition: lightmap.cpp:1347
void castLight(Out(&output_cache)[MAPSIZE_X][MAPSIZE_Y], const T(&input_array)[MAPSIZE_X][MAPSIZE_Y], const point &offset, int offsetDistance, T numerator=VISIBILITY_FULL, int row=1, float start=1.0f, float end=0.0f, T cumulative_transparency=LIGHT_TRANSPARENCY_OPEN_AIR)
Definition: lightmap.cpp:1083
direction
Definition: line.h:39
void update_light_quadrants(four_quadrants &update, const float &new_value, quadrant q)
Definition: shadowcasting.h:96
float accumulate_transparency(const float &cumulative_transparency, const float &current_transparency, const int &distance)

References accumulate_transparency(), castLight(), get_cache(), light_calc(), light_check(), MAPSIZE_X, MAPSIZE_Y, update_light_quadrants(), tripoint::xy(), and tripoint::z.

Referenced by generate_lightmap().

◆ apply_faction_ownership()

void map::apply_faction_ownership ( const point p1,
const point p2,
const faction_id id 
)

Definition at line 5494 of file mapgen.cpp.

5495{
5496 for( const tripoint &p : points_in_rectangle( tripoint( p1, abs_sub.z ), tripoint( p2,
5497 abs_sub.z ) ) ) {
5498 auto items = i_at( p.xy() );
5499 for( item &elem : items ) {
5500 elem.set_owner( id );
5501 }
5502 vehicle *source_veh = veh_pointer_or_null( veh_at( p ) );
5503 if( source_veh ) {
5504 if( !source_veh->has_owner() ) {
5505 source_veh->set_owner( id );
5506 }
5507 }
5508 }
5509}
tripoint_range< tripoint > points_in_rectangle(const tripoint &from, const tripoint &to) const
Definition: map.cpp:8412
bool has_owner() const
Definition: vehicle.h:844
void set_owner(const faction_id &new_owner)
Definition: vehicle.h:831

References abs_sub, vehicle::has_owner(), i_at(), points_in_rectangle(), vehicle::set_owner(), veh_at(), veh_pointer_or_null(), and tripoint::z.

Referenced by jmapgen_faction::apply().

◆ apply_light_arc()

void map::apply_light_arc ( const tripoint p,
units::angle  angle,
float  luminance,
units::angle  wideangle = 30_degrees 
)
private

Definition at line 1478 of file lightmap.cpp.

1480{
1481 if( luminance <= LIGHT_SOURCE_LOCAL ) {
1482 return;
1483 }
1484
1485 bool lit[LIGHTMAP_CACHE_X][LIGHTMAP_CACHE_Y] {};
1486
1488
1489 // Normalize (should work with negative values too)
1490 const units::angle wangle = wideangle / 2.0;
1491
1492 units::angle nangle = fmod( angle, 360_degrees );
1493
1494 tripoint end;
1495 int range = LIGHT_RANGE( luminance );
1496 calc_ray_end( nangle, range, p, end );
1497 apply_light_ray( lit, p, end, luminance );
1498
1499 tripoint test;
1500 calc_ray_end( wangle + nangle, range, p, test );
1501
1502 const float wdist = hypot( end.x - test.x, end.y - test.y );
1503 if( wdist <= 0.5 ) {
1504 return;
1505 }
1506
1507 // attempt to determine beam intensity required to cover all squares
1508 const units::angle wstep = ( wangle / ( wdist * M_SQRT2 ) );
1509
1510 // NOLINTNEXTLINE(clang-analyzer-security.FloatLoopCounter)
1511 for( units::angle ao = wstep; ao <= wangle; ao += wstep ) {
1512 if( trigdist ) {
1513 double fdist = ( ao * M_PI_2 ) / wangle;
1514 end.x = static_cast<int>(
1515 p.x + ( static_cast<double>( range ) - fdist * 2.0 ) * cos( nangle + ao ) );
1516 end.y = static_cast<int>(
1517 p.y + ( static_cast<double>( range ) - fdist * 2.0 ) * sin( nangle + ao ) );
1518 apply_light_ray( lit, p, end, luminance );
1519
1520 end.x = static_cast<int>(
1521 p.x + ( static_cast<double>( range ) - fdist * 2.0 ) * cos( nangle - ao ) );
1522 end.y = static_cast<int>(
1523 p.y + ( static_cast<double>( range ) - fdist * 2.0 ) * sin( nangle - ao ) );
1524 apply_light_ray( lit, p, end, luminance );
1525 } else {
1526 calc_ray_end( nangle + ao, range, p, end );
1527 apply_light_ray( lit, p, end, luminance );
1528 calc_ray_end( nangle - ao, range, p, end );
1529 apply_light_ray( lit, p, end, luminance );
1530 }
1531 }
1532}
bool trigdist
Circular distances.
void apply_light_ray(bool lit[MAPSIZE_X][MAPSIZE_Y], const tripoint &s, const tripoint &e, float luminance)
Definition: lightmap.cpp:1534
static constexpr int LIGHTMAP_CACHE_Y
Definition: lightmap.cpp:48
static constexpr int LIGHTMAP_CACHE_X
Definition: lightmap.cpp:47
static constexpr float LIGHT_SOURCE_LOCAL
Definition: lightmap.h:8
#define LIGHT_RANGE(b)
Definition: lightmap.h:41
void calc_ray_end(units::angle angle, const int range, const tripoint &p, tripoint &out)
Definition: line.cpp:751
#define M_SQRT2
Definition: math_defines.h:29
#define M_PI_2
Definition: math_defines.h:25
quantity< double, angle_in_radians_tag > angle
Definition: units_angle.h:17
double sin(angle a)
Definition: units_angle.h:52
double cos(angle a)
Definition: units_angle.h:57
quantity< V, U > fmod(quantity< V, U > num, quantity< V, U > den)
Definition: units_def.h:142

References apply_light_ray(), apply_light_source(), calc_ray_end(), units::cos(), units::fmod(), LIGHT_RANGE, LIGHT_SOURCE_LOCAL, LIGHTMAP_CACHE_X, LIGHTMAP_CACHE_Y, M_PI_2, M_SQRT2, units::sin(), trigdist, tripoint::x, and tripoint::y.

Referenced by add_light_from_items(), and generate_lightmap().

◆ apply_light_ray()

void map::apply_light_ray ( bool  lit[MAPSIZE_X][MAPSIZE_Y],
const tripoint s,
const tripoint e,
float  luminance 
)
private

Definition at line 1534 of file lightmap.cpp.

1536{
1537 point a( std::abs( e.x - s.x ) * 2, std::abs( e.y - s.y ) * 2 );
1538 point d( ( s.x < e.x ) ? 1 : -1, ( s.y < e.y ) ? 1 : -1 );
1539 point p( s.xy() );
1540
1541 quadrant quad = quadrant_from_x_y( d.x, d.y );
1542
1543 // TODO: Invert that z comparison when it's sane
1544 if( s.z != e.z || ( s.x == e.x && s.y == e.y ) ) {
1545 return;
1546 }
1547
1548 auto &lm = get_cache( s.z ).lm;
1549 auto &transparency_cache = get_cache( s.z ).transparency_cache;
1550
1551 float distance = 1.0;
1552 float transparency = LIGHT_TRANSPARENCY_OPEN_AIR;
1553 const float scaling_factor = static_cast<float>( rl_dist( s, e ) ) /
1554 static_cast<float>( square_dist( s, e ) );
1555 // TODO: [lightmap] Pull out the common code here rather than duplication
1556 if( a.x > a.y ) {
1557 int t = a.y - ( a.x / 2 );
1558 do {
1559 if( t >= 0 ) {
1560 p.y += d.y;
1561 t -= a.x;
1562 }
1563
1564 p.x += d.x;
1565 t += a.y;
1566
1567 // TODO: clamp coordinates to map bounds before this method is called.
1568 if( lightmap_boundaries.contains( p ) ) {
1569 float current_transparency = transparency_cache[p.x][p.y];
1570 bool is_opaque = ( current_transparency == LIGHT_TRANSPARENCY_SOLID );
1571 if( !lit[p.x][p.y] ) {
1572 // Multiple rays will pass through the same squares so we need to record that
1573 lit[p.x][p.y] = true;
1574 float lm_val = luminance / ( fastexp( transparency * distance ) * distance );
1575 quadrant q = is_opaque ? quad : quadrant::default_;
1576 lm[p.x][p.y][q] = std::max( lm[p.x][p.y][q], lm_val );
1577 }
1578 if( is_opaque ) {
1579 break;
1580 }
1581 // Cumulative average of the transparency values encountered.
1582 transparency = ( ( distance - 1.0 ) * transparency + current_transparency ) / distance;
1583 } else {
1584 break;
1585 }
1586
1587 distance += scaling_factor;
1588 } while( !( p.x == e.x && p.y == e.y ) );
1589 } else {
1590 int t = a.x - ( a.y / 2 );
1591 do {
1592 if( t >= 0 ) {
1593 p.x += d.x;
1594 t -= a.y;
1595 }
1596
1597 p.y += d.y;
1598 t += a.x;
1599
1600 if( lightmap_boundaries.contains( p ) ) {
1601 float current_transparency = transparency_cache[p.x][p.y];
1602 bool is_opaque = ( current_transparency == LIGHT_TRANSPARENCY_SOLID );
1603 if( !lit[p.x][p.y] ) {
1604 // Multiple rays will pass through the same squares so we need to record that
1605 lit[p.x][p.y] = true;
1606 float lm_val = luminance / ( fastexp( transparency * distance ) * distance );
1607 quadrant q = is_opaque ? quad : quadrant::default_;
1608 lm[p.x][p.y][q] = std::max( lm[p.x][p.y][q], lm_val );
1609 }
1610 if( is_opaque ) {
1611 break;
1612 }
1613 // Cumulative average of the transparency values encountered.
1614 transparency = ( ( distance - 1.0 ) * transparency + current_transparency ) / distance;
1615 } else {
1616 break;
1617 }
1618
1619 distance += scaling_factor;
1620 } while( !( p.x == e.x && p.y == e.y ) );
1621 }
1622}
int square_dist(const coords::coord_point< Point, Origin, Scale > &loc1, const coords::coord_point< Point, Origin, Scale > &loc2)
Definition: coordinates.h:505
static constexpr quadrant quadrant_from_x_y(int x, int y)
Definition: lightmap.cpp:784
static float fastexp(float x)
Definition: lightmap.cpp:1331
static constexpr float LIGHT_TRANSPARENCY_OPEN_AIR
Definition: lightmap.h:36
quadrant
Definition: shadowcasting.h:21

References a, default_, fastexp(), get_cache(), LIGHT_TRANSPARENCY_OPEN_AIR, LIGHT_TRANSPARENCY_SOLID, lightmap_boundaries, level_cache::lm, quadrant_from_x_y(), rl_dist(), square_dist(), level_cache::transparency_cache, point::x, tripoint::x, tripoint::xy(), point::y, tripoint::y, and tripoint::z.

Referenced by apply_light_arc().

◆ apply_light_source()

void map::apply_light_source ( const tripoint p,
float  luminance 
)
private

Definition at line 1359 of file lightmap.cpp.

1360{
1361 auto &cache = get_cache( p.z );
1362 four_quadrants( &lm )[MAPSIZE_X][MAPSIZE_Y] = cache.lm;
1363 float ( &sm )[MAPSIZE_X][MAPSIZE_Y] = cache.sm;
1364 float ( &transparency_cache )[MAPSIZE_X][MAPSIZE_Y] = cache.transparency_cache;
1365 float ( &light_source_buffer )[MAPSIZE_X][MAPSIZE_Y] = cache.light_source_buffer;
1366
1367 const point p2( p.xy() );
1368
1369 if( inbounds( p ) ) {
1370 const float min_light = std::max( static_cast<float>( lit_level::LOW ), luminance );
1371 lm[p2.x][p2.y] = elementwise_max( lm[p2.x][p2.y], min_light );
1372 sm[p2.x][p2.y] = std::max( sm[p2.x][p2.y], luminance );
1373 }
1374 if( luminance <= lit_level::LOW ) {
1375 return;
1376 } else if( luminance <= lit_level::BRIGHT_ONLY ) {
1377 luminance = 1.49f;
1378 }
1379
1380 /* If we're a 5 luminance fire , we skip casting rays into ey && sx if we have
1381 neighboring fires to the north and west that were applied via light_source_buffer
1382 If there's a 1 luminance candle east in buffer, we still cast rays into ex since it's smaller
1383 If there's a 100 luminance magnesium flare south added via apply_light_source instead od
1384 add_light_source, it's unbuffered so we'll still cast rays into sy.
1385
1386 ey
1387 nnnNnnn
1388 w e
1389 w 5 +e
1390 sx W 5*1+E ex
1391 w ++++e
1392 w+++++e
1393 sssSsss
1394 sy
1395 */
1396 const int peer_inbounds = LIGHTMAP_CACHE_X - 1;
1397 bool north = ( p2.y != 0 && light_source_buffer[p2.x][p2.y - 1] < luminance );
1398 bool south = ( p2.y != peer_inbounds && light_source_buffer[p2.x][p2.y + 1] < luminance );
1399 bool east = ( p2.x != peer_inbounds && light_source_buffer[p2.x + 1][p2.y] < luminance );
1400 bool west = ( p2.x != 0 && light_source_buffer[p2.x - 1][p2.y] < luminance );
1401
1402 if( north ) {
1403 castLight < 1, 0, 0, -1, float, four_quadrants, light_calc, light_check,
1405 lm, transparency_cache, p2, 0, luminance );
1406 castLight < -1, 0, 0, -1, float, four_quadrants, light_calc, light_check,
1408 lm, transparency_cache, p2, 0, luminance );
1409 }
1410
1411 if( east ) {
1412 castLight < 0, -1, 1, 0, float, four_quadrants, light_calc, light_check,
1414 lm, transparency_cache, p2, 0, luminance );
1415 castLight < 0, -1, -1, 0, float, four_quadrants, light_calc, light_check,
1417 lm, transparency_cache, p2, 0, luminance );
1418 }
1419
1420 if( south ) {
1421 castLight<1, 0, 0, 1, float, four_quadrants, light_calc, light_check,
1423 lm, transparency_cache, p2, 0, luminance );
1424 castLight < -1, 0, 0, 1, float, four_quadrants, light_calc, light_check,
1426 lm, transparency_cache, p2, 0, luminance );
1427 }
1428
1429 if( west ) {
1430 castLight<0, 1, 1, 0, float, four_quadrants, light_calc, light_check,
1432 lm, transparency_cache, p2, 0, luminance );
1433 castLight < 0, 1, -1, 0, float, four_quadrants, light_calc, light_check,
1435 lm, transparency_cache, p2, 0, luminance );
1436 }
1437}
constexpr scale sm
Definition: coordinates.h:31

References accumulate_transparency(), BRIGHT_ONLY, castLight(), get_cache(), inbounds(), light_calc(), light_check(), LIGHTMAP_CACHE_X, LOW, MAPSIZE_X, MAPSIZE_Y, coords::sm, update_light_quadrants(), point::x, tripoint::xy(), point::y, and tripoint::z.

Referenced by apply_character_light(), apply_light_arc(), and generate_lightmap().

◆ bash()

bash_results map::bash ( const tripoint p,
int  str,
bool  silent = false,
bool  destroy = false,
bool  bash_floor = false,
const vehicle bashing_vehicle = nullptr 
)

Returns a pair where first is whether anything was smashed and second is if it was destroyed.

Parameters
pWhere to bash
strHow hard to bash
silentDon't produce any sound
destroyDestroys some otherwise unbashable tiles
bash_floorAllow bashing the floor and the tile that supports it
bashing_vehicleVehicle that should NOT be bashed (because it is doing the bashing)

Definition at line 3506 of file map.cpp.

3509{
3510 bash_params bsh{
3511 str, silent, destroy, bash_floor, static_cast<float>( rng_float( 0, 1.0f ) ), false, true
3512 };
3514 if( !inbounds( p ) ) {
3515 return result;
3516 }
3517
3518 bool bashed_sealed = false;
3519 if( has_flag( "SEALED", p ) ) {
3520 result |= bash_ter_furn( p, bsh );
3521 bashed_sealed = true;
3522 }
3523
3524 result |= bash_field( p, bsh );
3525
3526 // Don't bash items inside terrain/furniture with SEALED flag
3527 if( !bashed_sealed ) {
3528 result |= bash_items( p, bsh );
3529 }
3530 // Don't bash the vehicle doing the bashing
3531 const vehicle *veh = veh_pointer_or_null( veh_at( p ) );
3532 if( veh != nullptr && veh != bashing_vehicle ) {
3533 result |= bash_vehicle( p, bsh );
3534 }
3535
3536 // If we still didn't bash anything solid (a vehicle) or a tile with SEALED flag, bash ter/furn
3537 if( !result.bashed_solid && !bashed_sealed ) {
3538 result |= bash_ter_furn( p, bsh );
3539 }
3540
3541 return result;
3542}
bash_results bash_field(const tripoint &p, const bash_params &params)
Definition: map.cpp:3596
bash_results bash_items(const tripoint &p, const bash_params &params)
Definition: map.cpp:3544
bash_results bash_vehicle(const tripoint &p, const bash_params &params)
Definition: map.cpp:3578
bash_results bash_ter_furn(const tripoint &p, const bash_params &params)
Definition: map.cpp:3382
double rng_float(double lo, double hi)
Definition: rng.cpp:28
@ silent
Definition: weather_type.h:56

References bash_field(), bash_items(), bash_ter_furn(), bash_vehicle(), destroy(), has_flag(), inbounds(), rng_float(), silent, veh_at(), and veh_pointer_or_null().

Referenced by Character::activate_bionic(), jmapgen_setmap::apply(), bash_furn_success(), bash_resistance(), bash_strength(), bash_ter_furn(), bash_ter_success(), batter(), destroy(), destroy_furn(), explosion_handler::do_blast(), drop_furniture(), drop_items(), game::fling_creature(), is_bashable(), game::knockback(), npc::move_to(), vehicle::part_collision(), route(), shoot(), explosion_handler::shrapnel(), mattack::shriek_stun(), smash(), and valid_move().

◆ bash_field()

bash_results map::bash_field ( const tripoint p,
const bash_params params 
)

Definition at line 3596 of file map.cpp.

3597{
3599 if( get_field( p, fd_web ) != nullptr ) {
3600 result.did_bash = true;
3601 result.bashed_solid = true; // To prevent bashing furniture/vehicles
3602 remove_field( p, fd_web );
3603 }
3604
3605 return result;
3606}
void remove_field(const tripoint &p, const field_type_id &field_to_remove)
Remove field entry at xy, ignored if the field entry is not present.
Definition: map.cpp:5443
field_type_id fd_web
Definition: field_type.cpp:340

References fd_web, get_field(), and remove_field().

Referenced by bash().

◆ bash_furn_success()

bash_results map::bash_furn_success ( const tripoint p,
const bash_params params 
)

Definition at line 3286 of file map.cpp.

3287{
3289 const auto &furnid = furn( p ).obj();
3290 const map_bash_info &bash = furnid.bash;
3291
3292
3293 if( has_flag_furn( "FUNGUS", p ) ) {
3294 fungal_effects( *g, *this ).create_spores( p );
3295 }
3296 std::string soundfxvariant = furnid.id.str();
3297 const bool tent = !bash.tent_centers.empty();
3298
3299 // Special code to collapse the tent if destroyed
3300 if( tent ) {
3301 // Get ids of possible centers
3302 std::set<furn_id> centers;
3303 for( const auto &cur_id : bash.tent_centers ) {
3304 if( cur_id.is_valid() ) {
3305 centers.insert( cur_id );
3306 }
3307 }
3308
3310
3311 // Find the center of the tent
3312 // First check if we're not currently bashing the center
3313 if( centers.count( furn( p ) ) > 0 ) {
3314 tentp.emplace( p, furn( p ) );
3315 } else {
3316 for( const tripoint &pt : points_in_radius( p, bash.collapse_radius ) ) {
3317 const furn_id &f_at = furn( pt );
3318 // Check if we found the center of the current tent
3319 if( centers.count( f_at ) > 0 ) {
3320 tentp.emplace( pt, f_at );
3321 break;
3322 }
3323 }
3324 }
3325 // Didn't find any tent center, wreck the current tile
3326 if( !tentp ) {
3328 furn_set( p, bash.furn_set );
3329 } else {
3330 // Take the tent down
3331 const int rad = tentp->second.obj().bash.collapse_radius;
3332 for( const tripoint &pt : points_in_radius( tentp->first, rad ) ) {
3333 const furn_id frn = furn( pt );
3334 if( frn == f_null ) {
3335 continue;
3336 }
3337
3338 const map_bash_info &recur_bash = frn.obj().bash;
3339 // Check if we share a center type and thus a "tent type"
3340 for( const auto &cur_id : recur_bash.tent_centers ) {
3341 if( centers.count( cur_id.id() ) > 0 ) {
3342 // Found same center, wreck current tile
3344 furn_set( pt, recur_bash.furn_set );
3345 break;
3346 }
3347 }
3348 }
3349 }
3350 soundfxvariant = "smash_cloth";
3351 } else {
3352 furn_set( p, bash.furn_set );
3353 for( item &it : i_at( p ) ) {
3354 it.on_drop( p, *this );
3355 }
3356 // HACK: Hack alert.
3357 // Signs have cosmetics associated with them on the submap since
3358 // furniture can't store dynamic data to disk. To prevent writing
3359 // mysteriously appearing for a sign later built here, remove the
3360 // writing from the submap.
3361 delete_signage( p );
3362 }
3363
3364 if( !tent ) {
3366 }
3367
3368 if( !bash.sound.empty() && !params.silent ) {
3369 static const std::string soundfxid = "smash_success";
3370 int sound_volume = get_sound_volume( bash );
3371 sounds::sound( p, sound_volume, sounds::sound_t::combat, bash.sound, false,
3372 soundfxid, soundfxvariant );
3373 }
3374
3375 if( bash.explosive > 0 ) {
3376 explosion_handler::explosion( p, bash.explosive, 0.8, false );
3377 }
3378
3379 return result;
3380}
T & emplace(Args &&... args)
Definition: optional.h:143
void create_spores(const tripoint &p, Creature *origin=nullptr)
Makes spores at p.
bool has_flag_furn(const std::string &flag, const tripoint &p) const
Definition: map.cpp:2312
bash_results bash(const tripoint &p, int str, bool silent=false, bool destroy=false, bool bash_floor=false, const vehicle *bashing_vehicle=nullptr)
Returns a pair where first is whether anything was smashed and second is if it was destroyed.
Definition: map.cpp:3506
std::vector< item * > spawn_items(const tripoint &p, const std::vector< item > &new_items)
Definition: map.cpp:4142
void furn_set(const tripoint &p, const furn_id &new_furniture, cata::poly_serialized< active_tile_data > new_active=nullptr)
Sets the furniture at given position.
Definition: map.cpp:1355
void delete_signage(const tripoint &p) const
Definition: map.cpp:4001
static int get_sound_volume(const map_bash_info &bash)
Definition: map.cpp:3149
furn_id f_null
Definition: mapdata.cpp:1095
void explosion(const tripoint &p, float power, float factor, bool fire, int legacy_casing_mass, float)
Legacy explosion function.
Definition: explosion.cpp:686
ItemList items_from(const item_group_id &group_id, const time_point &birthday)
Create items from the given group.
Definition: item_group.cpp:574
void sound(const tripoint &p, int vol, sound_t category, const std::string &description, bool ambient=false, const std::string &id="", const std::string &variant="default")
Sound at (p) of intensity (vol)
Definition: sounds.cpp:177
bool silent
Definition: map.h:132
std::vector< furn_str_id > tent_centers
Definition: mapdata.h:100
item_group_id drop_group
Definition: mapdata.h:86
furn_str_id furn_set
Definition: mapdata.h:98
map_bash_info bash
Definition: mapdata.h:344

References bash(), map_data_common_t::bash, sounds::combat, fungal_effects::create_spores(), delete_signage(), map_bash_info::drop_group, cata::optional< T >::emplace(), explosion_handler::explosion(), f_null, furn(), furn_set(), map_bash_info::furn_set, g, get_sound_volume(), has_flag_furn(), i_at(), item_group::items_from(), int_id< T >::obj(), points_in_radius(), bash_params::silent, sounds::sound(), spawn_items(), map_bash_info::tent_centers, and calendar::turn.

Referenced by bash_ter_furn().

◆ bash_items()

bash_results map::bash_items ( const tripoint p,
const bash_params params 
)

Definition at line 3544 of file map.cpp.

3545{
3547 if( !has_items( p ) ) {
3548 return result;
3549 }
3550
3551 std::vector<item> smashed_contents;
3552 auto bashed_items = i_at( p );
3553 bool smashed_glass = false;
3554 for( auto bashed_item = bashed_items.begin(); bashed_item != bashed_items.end(); ) {
3555 // the check for active suppresses Molotovs smashing themselves with their own explosion
3556 if( bashed_item->made_of( material_id( "glass" ) ) && !bashed_item->active && one_in( 2 ) ) {
3557 result.did_bash = true;
3558 smashed_glass = true;
3559 for( const item *bashed_content : bashed_item->contents.all_items_top() ) {
3560 smashed_contents.push_back( item( *bashed_content ) );
3561 }
3562 bashed_item = bashed_items.erase( bashed_item );
3563 } else {
3564 ++bashed_item;
3565 }
3566 }
3567 // Now plunk in the contents of the smashed items.
3568 spawn_items( p, smashed_contents );
3569
3570 // Add a glass sound even when something else also breaks
3571 if( smashed_glass && !params.silent ) {
3572 sounds::sound( p, 12, sounds::sound_t::combat, _( "glass shattering" ), false,
3573 "smash_success", "smash_glass_contents" );
3574 }
3575 return result;
3576}
std::list< item * > all_items_top()
returns a list of pointers to all top-level items
item_contents contents
Definition: item.h:2157
bool has_items(const tripoint &p) const
Checks for existence of items.
Definition: map.cpp:4750

References _, item_contents::all_items_top(), sounds::combat, item::contents, has_items(), i_at(), one_in(), bash_params::silent, sounds::sound(), and spawn_items().

Referenced by bash().

◆ bash_rating() [1/2]

int map::bash_rating ( const int  str,
const point p 
) const
inline

Definition at line 1022 of file map.h.

1022 {
1023 return bash_rating( str, tripoint( p, abs_sub.z ) );
1024 }
int bash_rating(int str, const tripoint &p, bool allow_floor=false) const
Returns a success rating from -1 to 10 for a given tile based on a set strength, used for AI movement...
Definition: map.cpp:2472

References abs_sub, bash_rating(), and tripoint::z.

◆ bash_rating() [2/2]

int map::bash_rating ( int  str,
const tripoint p,
bool  allow_floor = false 
) const

Returns a success rating from -1 to 10 for a given tile based on a set strength, used for AI movement planning Values roughly correspond to 10% increment chances of success on a given bash, rounded down.

-1 means the square is not bashable

Definition at line 2472 of file map.cpp.

2473{
2474 if( !inbounds( p ) ) {
2475 dbg( DL::Warn ) << "Looking for out-of-bounds is_bashable at " << p;
2476 return -1;
2477 }
2478
2479 if( str <= 0 ) {
2480 return -1;
2481 }
2482
2483 const furn_t &furniture = furn( p ).obj();
2484 const ter_t &terrain = ter( p ).obj();
2485 const optional_vpart_position vp = veh_at( p );
2486 vehicle *const veh = vp ? &vp->vehicle() : nullptr;
2487 const int part = vp ? vp->part_index() : -1;
2488 return bash_rating_internal( str, furniture, terrain, allow_floor, veh, part );
2489}
int bash_rating_internal(int str, const furn_t &furniture, const ter_t &terrain, bool allow_floor, const vehicle *veh, int part) const
Definition: map.cpp:2364

References bash_rating_internal(), dbg, furn(), furniture, inbounds(), int_id< T >::obj(), ter(), terrain, veh_at(), and Warn.

Referenced by bash_rating(), npc::can_move_to(), monster::move(), and npc::move_to().

◆ bash_rating_internal()

int map::bash_rating_internal ( int  str,
const furn_t furniture,
const ter_t terrain,
bool  allow_floor,
const vehicle veh,
int  part 
) const
private
Strength determines what furniture can be smashed Strength determines what terrain can be smashed Strength increases smashing damage

Definition at line 2364 of file map.cpp.

2367{
2368 bool furn_smash = false;
2369 bool ter_smash = false;
2370 ///\EFFECT_STR determines what furniture can be smashed
2371 if( furniture.id && furniture.bash.str_max != -1 ) {
2372 furn_smash = true;
2373 ///\EFFECT_STR determines what terrain can be smashed
2374 } else if( terrain.bash.str_max != -1 && ( !terrain.bash.bash_below || allow_floor ) ) {
2375 ter_smash = true;
2376 }
2377
2378 if( veh != nullptr && vpart_position( const_cast<vehicle &>( *veh ), part ).obstacle_at_part() ) {
2379 // Monsters only care about rating > 0, NPCs should want to path around cars instead
2380 return 2; // Should probably be a function of part hp (+armor on tile)
2381 }
2382
2383 int bash_min = 0;
2384 int bash_max = 0;
2385 if( furn_smash ) {
2386 bash_min = furniture.bash.str_min;
2387 bash_max = furniture.bash.str_max;
2388 } else if( ter_smash ) {
2389 bash_min = terrain.bash.str_min;
2390 bash_max = terrain.bash.str_max;
2391 } else {
2392 return -1;
2393 }
2394
2395 ///\EFFECT_STR increases smashing damage
2396 if( str < bash_min ) {
2397 return 0;
2398 } else if( str >= bash_max ) {
2399 return 10;
2400 }
2401
2402 int ret = ( 10 * ( str - bash_min ) ) / ( bash_max - bash_min );
2403 // Round up to 1, so that desperate NPCs can try to bash down walls
2404 return std::max( ret, 1 );
2405}
Reference to a position (a point) of the vehicle.

References furniture, cata::hash64_detail::ret, and terrain.

Referenced by bash_rating(), and route().

◆ bash_resistance() [1/2]

int map::bash_resistance ( const point p) const
inline

Definition at line 1016 of file map.h.

1016 {
1017 return bash_resistance( tripoint( p, abs_sub.z ) );
1018 }
int bash_resistance(const tripoint &p, bool allow_floor=false) const
Returns min_str of the furniture or terrain at p.
Definition: map.cpp:2458

References abs_sub, bash_resistance(), and tripoint::z.

◆ bash_resistance() [2/2]

int map::bash_resistance ( const tripoint p,
bool  allow_floor = false 
) const

Returns min_str of the furniture or terrain at p.

Definition at line 2458 of file map.cpp.

2459{
2460 if( has_furn( p ) && furn( p ).obj().bash.str_min != -1 ) {
2461 return furn( p ).obj().bash.str_min;
2462 }
2463
2464 const auto &ter_bash = ter( p ).obj().bash;
2465 if( ter_bash.str_min != -1 && ( !ter_bash.bash_below || allow_floor ) ) {
2466 return ter_bash.str_min;
2467 }
2468
2469 return -1;
2470}
bool has_furn(const tripoint &p) const
Definition: map.cpp:1338
int str_min
Definition: mapdata.h:62

References bash(), map_data_common_t::bash, furn(), has_furn(), int_id< T >::obj(), map_bash_info::str_min, and ter().

Referenced by bash_resistance(), ranged::expected_coverage(), vehicle::part_collision(), rate_location(), smash(), and terrain_collision_data().

◆ bash_strength() [1/2]

int map::bash_strength ( const point p) const
inline

Definition at line 1011 of file map.h.

1011 {
1012 return bash_strength( tripoint( p, abs_sub.z ) );
1013 }
int bash_strength(const tripoint &p, bool allow_floor=false) const
Returns max_str of the furniture or terrain at p.
Definition: map.cpp:2444

References abs_sub, bash_strength(), and tripoint::z.

◆ bash_strength() [2/2]

int map::bash_strength ( const tripoint p,
bool  allow_floor = false 
) const

Returns max_str of the furniture or terrain at p.

Definition at line 2444 of file map.cpp.

2445{
2446 if( has_furn( p ) && furn( p ).obj().bash.str_max != -1 ) {
2447 return furn( p ).obj().bash.str_max;
2448 }
2449
2450 const auto &ter_bash = ter( p ).obj().bash;
2451 if( ter_bash.str_max != -1 && ( !ter_bash.bash_below || allow_floor ) ) {
2452 return ter_bash.str_max;
2453 }
2454
2455 return -1;
2456}
int str_max
Definition: mapdata.h:64

References bash(), map_data_common_t::bash, furn(), has_furn(), int_id< T >::obj(), map_bash_info::str_max, and ter().

Referenced by bash_strength(), ranged::expected_coverage(), game::fling_creature(), and terrain_collision_data().

◆ bash_ter_furn()

bash_results map::bash_ter_furn ( const tripoint p,
const bash_params params 
)

Definition at line 3382 of file map.cpp.

3383{
3385 std::string soundfxvariant;
3386 const auto &ter_obj = ter( p ).obj();
3387 const auto &furn_obj = furn( p ).obj();
3388 bool smash_ter = false;
3389 const map_bash_info *bash = nullptr;
3390
3391 if( furn_obj.id && furn_obj.bash.str_max != -1 ) {
3392 bash = &furn_obj.bash;
3393 soundfxvariant = furn_obj.id.str();
3394 } else if( ter_obj.bash.str_max != -1 ) {
3395 bash = &ter_obj.bash;
3396 smash_ter = true;
3397 soundfxvariant = ter_obj.id.str();
3398 }
3399
3400 // Floor bashing check
3401 // Only allow bashing floors when we want to bash floors and we're in z-level mode
3402 // Unless we're destroying, then it gets a little weird
3403 if( smash_ter && bash->bash_below && ( !zlevels || !params.bash_floor ) ) {
3404 if( !params.destroy ) {
3405 smash_ter = false;
3406 bash = nullptr;
3407 } else if( !bash->ter_set && zlevels ) {
3408 // HACK: A hack for destroy && !bash_floor
3409 // We have to check what would we create and cancel if it is what we have now
3410 tripoint below( p.xy(), p.z - 1 );
3411 const auto roof = get_roof( below, false );
3412 if( roof == ter( p ) ) {
3413 smash_ter = false;
3414 bash = nullptr;
3415 }
3416 } else if( !bash->ter_set && ter( p ) == t_dirt ) {
3417 // As above, except for no-z-levels case
3418 smash_ter = false;
3419 bash = nullptr;
3420 }
3421 }
3422
3423 // TODO: what if silent is true?
3424 if( has_flag( "ALARMED", p ) && !g->timed_events.queued( TIMED_EVENT_WANTED ) ) {
3425 sounds::sound( p, 40, sounds::sound_t::alarm, _( "an alarm go off!" ),
3426 false, "environment", "alarm" );
3427 // Blame nearby player
3428 if( rl_dist( g->u.pos(), p ) <= 3 ) {
3429 g->events().send<event_type::triggers_alarm>( g->u.getID() );
3430 const point abs = ms_to_sm_copy( getabs( p.xy() ) );
3431 g->timed_events.add( TIMED_EVENT_WANTED, calendar::turn + 30_minutes, 0,
3432 tripoint( abs, p.z ) );
3433 }
3434 }
3435
3436 if( bash == nullptr || ( bash->destroy_only && !params.destroy ) ) {
3437 // Nothing bashable here
3438 if( impassable( p ) ) {
3439 if( !params.silent ) {
3440 sounds::sound( p, 18, sounds::sound_t::combat, _( "thump!" ),
3441 false, "smash_fail", "default" );
3442 }
3443
3444 result.did_bash = true;
3445 result.bashed_solid = true;
3446 }
3447
3448 return result;
3449 }
3450
3451 result.did_bash = true;
3452 result.bashed_solid = true;
3453 result.success = params.destroy;
3454
3455 int smin = bash->str_min;
3456 int smax = bash->str_max;
3457 if( !params.destroy ) {
3458 if( bash->str_min_blocked != -1 || bash->str_max_blocked != -1 ) {
3459 if( furn_is_supported( *this, p ) ) {
3460 if( bash->str_min_blocked != -1 ) {
3461 smin = bash->str_min_blocked;
3462 }
3463 if( bash->str_max_blocked != -1 ) {
3464 smax = bash->str_max_blocked;
3465 }
3466 }
3467 }
3468
3469 if( bash->str_min_supported != -1 || bash->str_max_supported != -1 ) {
3470 tripoint below( p.xy(), p.z - 1 );
3471 if( !zlevels || has_flag( TFLAG_SUPPORTS_ROOF, below ) ) {
3472 if( bash->str_min_supported != -1 ) {
3473 smin = bash->str_min_supported;
3474 }
3475 if( bash->str_max_supported != -1 ) {
3476 smax = bash->str_max_supported;
3477 }
3478 }
3479 }
3480 // Linear interpolation from str_min to str_max
3481 const int resistance = smin + ( params.roll * ( smax - smin ) );
3482 if( params.strength >= resistance ) {
3483 result.success = true;
3484 }
3485 }
3486
3487 if( !result.success ) {
3488 int sound_volume = bash->sound_fail_vol.value_or( 12 );
3489
3490 result.did_bash = true;
3491 if( !params.silent ) {
3492 sounds::sound( p, sound_volume, sounds::sound_t::combat, bash->sound_fail, false,
3493 "smash_fail", soundfxvariant );
3494 }
3495 } else {
3496 if( smash_ter ) {
3497 result |= bash_ter_success( p, params );
3498 } else {
3499 result |= bash_furn_success( p, params );
3500 }
3501 }
3502
3503 return result;
3504}
ter_id get_roof(const tripoint &p, bool allow_air) const
Definition: map.cpp:3089
bash_results bash_furn_success(const tripoint &p, const bash_params &params)
Definition: map.cpp:3286
bash_results bash_ter_success(const tripoint &p, const bash_params &params)
Definition: map.cpp:3157
point ms_to_sm_copy(const point &p)
static bool furn_is_supported(const map &m, const tripoint &p)
Definition: map.cpp:3133
ter_id t_dirt
Definition: mapdata.cpp:625
@ TFLAG_SUPPORTS_ROOF
Definition: mapdata.h:280
float roll
Value from 0.0 to 1.0 that affects interpolation between str_min and str_max At 0....
Definition: map.h:143
bool bash_floor
Definition: map.h:136
bool destroy
Definition: map.h:134
int strength
Definition: map.h:130
@ TIMED_EVENT_WANTED
Definition: timed_event.h:13

References _, sounds::alarm, bash(), bash_params::bash_floor, bash_furn_success(), bash_ter_success(), sounds::combat, bash_params::destroy, furn(), furn_is_supported(), g, get_roof(), getabs(), has_flag(), impassable(), ms_to_sm_copy(), int_id< T >::obj(), rl_dist(), bash_params::roll, bash_params::silent, sounds::sound(), bash_params::strength, t_dirt, ter(), TFLAG_SUPPORTS_ROOF, TIMED_EVENT_WANTED, triggers_alarm, calendar::turn, tripoint::xy(), tripoint::z, and zlevels.

Referenced by bash(), bash_ter_success(), and explosion_handler::do_blast_new().

◆ bash_ter_success()

bash_results map::bash_ter_success ( const tripoint p,
const bash_params params 
)

Definition at line 3157 of file map.cpp.

3158{
3160 result.success = true;
3161 const ter_t &ter_before = ter( p ).obj();
3162 const map_bash_info &bash = ter_before.bash;
3163 if( has_flag_ter( "FUNGUS", p ) ) {
3164 fungal_effects( *g, *this ).create_spores( p );
3165 }
3166 const std::string soundfxvariant = ter_before.id.str();
3167 const bool will_collapse = ter_before.has_flag( TFLAG_SUPPORTS_ROOF ) &&
3168 !ter_before.has_flag( TFLAG_INDOORS );
3169 const bool suspended = ter_before.has_flag( TFLAG_SUSPENDED );
3170 bool follow_below = false;
3171 if( params.bashing_from_above && bash.ter_set_bashed_from_above ) {
3172 // If this terrain is being bashed from above and this terrain
3173 // has a valid post-destroy bashed-from-above terrain, set it
3174 ter_set( p, bash.ter_set_bashed_from_above );
3175 } else if( bash.ter_set ) {
3176 // If the terrain has a valid post-destroy terrain, set it
3177 ter_set( p, bash.ter_set );
3178 follow_below |= zlevels && bash.bash_below;
3179 } else if( suspended ) {
3180 // Its important that we change the ter value before recursing, otherwise we'll hit an infinite loop.
3181 // This could be prevented by assembling a visited list, but in order to avoid that cost, we're going
3182 // build our recursion to just be resilient.
3183 ter_set( p, t_open_air );
3185 } else {
3186 tripoint below( p.xy(), p.z - 1 );
3187 const ter_t &ter_below = ter( below ).obj();
3188 // Only setting the flag here because we want drops and sounds in correct order
3189 follow_below |= zlevels && bash.bash_below && ter_below.roof;
3190
3191 ter_set( p, t_open_air );
3192 }
3193
3195
3196 if( !bash.sound.empty() && !params.silent ) {
3197 static const std::string soundfxid = "smash_success";
3198 int sound_volume = get_sound_volume( bash );
3199 sounds::sound( p, sound_volume, sounds::sound_t::combat, bash.sound, false,
3200 soundfxid, soundfxvariant );
3201 }
3202
3203 if( !zlevels ) {
3204 if( ter( p ) == t_open_air ) {
3205 // We destroyed something, so we aren't just "plugging" air with dirt here
3206 ter_set( p, t_dirt );
3207 }
3208 } else if( follow_below || ter( p ) == t_open_air ) {
3209 const tripoint below( p.xy(), p.z - 1 );
3210 // We may need multiple bashes in some weird cases
3211 // Example:
3212 // W has roof A
3213 // A bashes to B
3214 // B bashes to nothing
3215 // Below our point P, there is a W
3216 // If we bash down a B over a W, it might be from earlier A or just constructed over it!
3217 //
3218 // Current solution: bash roof until you reach same roof type twice, then bash down
3219 if( follow_below && params.do_recurse ) {
3220 bool blocked_by_roof = false;
3221 std::set<ter_id> encountered_types;
3222 encountered_types.insert( ter_before.id );
3223 encountered_types.insert( t_open_air );
3224 // Note: we're bashing the new roof, not the tile supported by it!
3225 int down_bash_tries = 10;
3226 do {
3227 const ter_id &ter_now = ter( p );
3228 if( encountered_types.count( ter_now ) != 0 ) {
3229 // We have encountered this type before and destroyed it (didn't block us)
3230 ter_set( p, t_open_air );
3231 bash_params params_below = params;
3232 params_below.bashing_from_above = true;
3233 params_below.bash_floor = false;
3234 params_below.do_recurse = false;
3235 params_below.destroy = true;
3236 int impassable_bash_tries = 10;
3237 // Unconditionally destroy, but don't go deeper
3238 do {
3239 result |= bash_ter_success( below, params_below );
3240 } while( ter( below )->movecost == 0 && impassable_bash_tries-- > 0 );
3241 if( impassable_bash_tries <= 0 ) {
3242 debugmsg( "Loop in terrain bashing for type %s", ter_before.id.str() );
3243 }
3244 } else if( ter_now == t_open_air ) {
3245 const ter_id &roof = get_roof( below, params.bash_floor && ter( below )->movecost != 0 );
3246 if( roof != t_open_air ) {
3247 ter_set( p, roof );
3248 }
3249 } else {
3250 // This floor/roof tile wasn't destroyed in this loop yet
3251 encountered_types.insert( ter_now );
3252 bash_params params_copy = params;
3253 params_copy.do_recurse = false;
3254 // TODO: Unwrap the calls, don't recurse
3255 // TODO: Don't bash furn
3256 bash_results results_sub = bash_ter_furn( p, params_copy );
3257 result |= results_sub;
3258 if( !results_sub.success ) {
3259 // Blocked, as in "the roof was too strong to bash"
3260 blocked_by_roof = true;
3261 }
3262 }
3263 } while( down_bash_tries-- > 0 && !blocked_by_roof &&
3264 ( ter( p ) != t_open_air || ter( p )->movecost == 0 || ter( below )->roof ) );
3265 if( down_bash_tries <= 0 ) {
3266 debugmsg( "Loop in terrain bashing for type %s", ter_before.id.str() );
3267 }
3268 } else {
3269 const ter_id &roof = get_roof( below, params.bash_floor && ter( below )->movecost != 0 );
3270
3271 ter_set( p, roof );
3272 }
3273 }
3274
3275 if( will_collapse && !has_flag( TFLAG_SUPPORTS_ROOF, p ) ) {
3276 collapse_at( p, params.silent, true, bash.explosive > 0 );
3277 }
3278
3279 if( bash.explosive > 0 ) {
3280 explosion_handler::explosion( p, bash.explosive, 0.8, false );
3281 }
3282
3283 return result;
3284}
void propagate_suspension_check(const tripoint &point)
Checks surrounding tiles for suspension, and has them check for collapse.
Definition: map.cpp:2938
void collapse_at(const tripoint &p, bool silent, bool was_supporting=false, bool destroy_pos=true)
Causes a collapse at p, such as from destroying a wall.
Definition: map.cpp:2893
const std::string & str() const
Returns the identifier as plain std::string.
Definition: string_id.h:255
@ TFLAG_SUSPENDED
Definition: mapdata.h:323
@ TFLAG_INDOORS
Definition: mapdata.h:291
bool do_recurse
Hack to prevent infinite recursion.
Definition: map.h:155
bool bashing_from_above
Definition: map.h:150
bool success
Definition: map.h:166
bool has_flag(const std::string &flag) const
Definition: mapdata.h:415
ter_str_id id
Definition: mapdata.h:458

References bash(), map_data_common_t::bash, bash_params::bash_floor, bash_ter_furn(), bash_ter_success(), bash_params::bashing_from_above, collapse_at(), sounds::combat, fungal_effects::create_spores(), debugmsg, bash_params::destroy, bash_params::do_recurse, explosion_handler::explosion(), g, get_roof(), get_sound_volume(), map_data_common_t::has_flag(), has_flag(), has_flag_ter(), ter_t::id, item_group::items_from(), int_id< T >::obj(), propagate_suspension_check(), ter_t::roof, bash_params::silent, sounds::sound(), spawn_items(), string_id< T >::str(), bash_results::success, t_dirt, t_open_air, ter(), ter_set(), TFLAG_INDOORS, TFLAG_SUPPORTS_ROOF, TFLAG_SUSPENDED, calendar::turn, tripoint::xy(), tripoint::z, and zlevels.

Referenced by bash_ter_furn(), bash_ter_success(), and shoot().

◆ bash_vehicle()

bash_results map::bash_vehicle ( const tripoint p,
const bash_params params 
)

Definition at line 3578 of file map.cpp.

3579{
3581 // Smash vehicle if present
3582 if( const optional_vpart_position vp = veh_at( p ) ) {
3583 vp->vehicle().damage( vp->part_index(), params.strength, DT_BASH );
3584 if( !params.silent ) {
3585 sounds::sound( p, 18, sounds::sound_t::combat, _( "crash!" ), false,
3586 "smash_success", "hit_vehicle" );
3587 }
3588
3589 result.did_bash = true;
3590 result.success = true;
3591 result.bashed_solid = true;
3592 }
3593 return result;
3594}
@ DT_BASH
Definition: damage.h:24

References _, sounds::combat, DT_BASH, bash_params::silent, sounds::sound(), bash_params::strength, and veh_at().

Referenced by bash().

◆ batter()

void map::batter ( const tripoint p,
int  power,
int  tries = 1,
bool  silent = false 
)

bash a square for a set number of times at set power.

Does not destroy

Definition at line 3643 of file map.cpp.

3644{
3645 int count = 0;
3646 while( count < tries && bash( p, power, silent ).success ) {
3647 count++;
3648 }
3649}
@ success
Definition: behavior.h:20

References bash(), detail::count(), silent, and behavior::success.

Referenced by activity_handlers::chop_tree_finish().

◆ board_vehicle()

void map::board_vehicle ( const tripoint p,
player pl 
)

Definition at line 1044 of file map.cpp.

1045{
1046 if( p == nullptr ) {
1047 debugmsg( "map::board_vehicle: null player" );
1048 return;
1049 }
1050
1052 true );
1053 if( !vp ) {
1054 if( p->grab_point.x == 0 && p->grab_point.y == 0 ) {
1055 debugmsg( "map::board_vehicle: vehicle not found" );
1056 }
1057 return;
1058 }
1059 if( vp->part().has_flag( vehicle_part::passenger_flag ) ) {
1060 player *psg = vp->vehicle().get_passenger( vp->part_index() );
1061 debugmsg( "map::board_vehicle: passenger (%s) is already there",
1062 psg ? psg->name : "<null>" );
1063 unboard_vehicle( pos );
1064 }
1065 vp->part().set_flag( vehicle_part::passenger_flag );
1066 vp->part().passenger_id = p->getID();
1067 vp->vehicle().invalidate_mass();
1068
1069 p->setpos( pos );
1070 p->in_vehicle = true;
1071 if( p->is_avatar() ) {
1072 g->update_map( g->u );
1073 }
1074}
std::string name
Definition: character.h:1570
void unboard_vehicle(const vpart_reference &, Character *passenger, bool dead_passenger=false)
Definition: map.cpp:1076
cata::optional< vpart_reference > part_with_feature(const std::string &f, bool unbroken) const
Definition: vehicle.cpp:2481
Definition: player.h:99
@ passenger_flag
Definition: vehicle.h:192
@ VPFLAG_BOARDABLE
Definition: veh_type.h:39

References debugmsg, g, Character::getID(), player::grab_point, Character::in_vehicle, Creature::is_avatar(), Character::name, optional_vpart_position::part_with_feature(), vehicle_part::passenger_flag, wrapped_vehicle::pos, Character::setpos(), unboard_vehicle(), veh_at(), VPFLAG_BOARDABLE, tripoint::x, and tripoint::y.

Referenced by debug_menu::debug(), npc::move_to(), game::phasing_move(), game::place_player(), game::swap_critters(), and avatar_action::swim().

◆ build_floor_cache()

bool map::build_floor_cache ( int  zlev)

Definition at line 7858 of file map.cpp.

7859{
7860 auto &ch = get_cache( zlev );
7861 if( !ch.floor_cache_dirty ) {
7862 return false;
7863 }
7864
7865 auto &floor_cache = ch.floor_cache;
7866 std::uninitialized_fill_n(
7867 &floor_cache[0][0], ( MAPSIZE_X ) * ( MAPSIZE_Y ), true );
7868
7869 bool lowest_z_lev = zlev <= -OVERMAP_DEPTH;
7870 for( int smx = 0; smx < my_MAPSIZE; ++smx ) {
7871 for( int smy = 0; smy < my_MAPSIZE; ++smy ) {
7872 const submap *cur_submap = get_submap_at_grid( { smx, smy, zlev } );
7873 const submap *below_submap = !lowest_z_lev ? get_submap_at_grid( { smx, smy, zlev - 1 } ) : nullptr;
7874
7875 if( cur_submap == nullptr ) {
7876 debugmsg( "Tried to build floor cache at (%d,%d,%d) but the submap is not loaded", smx, smy, zlev );
7877 continue;
7878 }
7879 if( !lowest_z_lev && below_submap == nullptr ) {
7880 debugmsg( "Tried to build floor cache at (%d,%d,%d) but the submap is not loaded", smx, smy,
7881 zlev - 1 );
7882 continue;
7883 }
7884
7885 for( int sx = 0; sx < SEEX; ++sx ) {
7886 for( int sy = 0; sy < SEEY; ++sy ) {
7887 point sp( sx, sy );
7888 const ter_t &terrain = cur_submap->get_ter( sp ).obj();
7889 if( terrain.has_flag( TFLAG_NO_FLOOR ) ) {
7890 if( below_submap && ( below_submap->get_furn( sp ).obj().has_flag( TFLAG_SUN_ROOF_ABOVE ) ) ) {
7891 continue;
7892 }
7893 const int x = sx + smx * SEEX;
7894 const int y = sy + smy * SEEY;
7895 floor_cache[x][y] = false;
7896 }
7897 }
7898 }
7899 }
7900 }
7901
7902 ch.floor_cache_dirty = false;
7903 return zlevels;
7904}
@ TFLAG_SUN_ROOF_ABOVE
Definition: mapdata.h:322
@ TFLAG_NO_FLOOR
Definition: mapdata.h:310
static const int sx[4]
Definition: tileray.cpp:10
static const int sy[4]
Definition: tileray.cpp:11

References debugmsg, get_cache(), get_submap_at_grid(), submap::get_ter(), MAPSIZE_X, MAPSIZE_Y, my_MAPSIZE, int_id< T >::obj(), OVERMAP_DEPTH, SEEX, SEEY, sx, sy, terrain, TFLAG_NO_FLOOR, TFLAG_SUN_ROOF_ABOVE, and zlevels.

Referenced by build_floor_caches(), and build_map_cache().

◆ build_floor_caches()

void map::build_floor_caches ( )

Definition at line 7906 of file map.cpp.

7907{
7908 const int minz = zlevels ? -OVERMAP_DEPTH : abs_sub.z;
7909 const int maxz = zlevels ? OVERMAP_HEIGHT : abs_sub.z;
7910 for( int z = minz; z <= maxz; z++ ) {
7911 build_floor_cache( z );
7912 }
7913}
bool build_floor_cache(int zlev)
Definition: map.cpp:7858

References abs_sub, build_floor_cache(), OVERMAP_DEPTH, OVERMAP_HEIGHT, tripoint::z, and zlevels.

Referenced by game::do_turn().

◆ build_map_cache()

void map::build_map_cache ( int  zlev,
bool  skip_lightmap = false 
)

Definition at line 8034 of file map.cpp.

8035{
8036 const int minz = zlevels ? -OVERMAP_DEPTH : zlev;
8037 const int maxz = zlevels ? OVERMAP_HEIGHT : zlev;
8038 bool seen_cache_dirty = false;
8039 for( int z = minz; z <= maxz; z++ ) {
8040 // trigger FOV recalculation only when there is a change on the player's level or if fov_3d is enabled
8041 const bool affects_seen_cache = z == zlev || fov_3d;
8045 seen_cache_dirty |= ( build_floor_cache( z ) && affects_seen_cache );
8046 seen_cache_dirty |= get_cache( z ).seen_cache_dirty && affects_seen_cache;
8047 }
8048 // needs a separate pass as it changes the caches on neighbour z-levels (e.g. floor_cache);
8049 // otherwise such changes might be overwritten by main cache-building logic
8050 for( int z = minz; z <= maxz; z++ ) {
8051 do_vehicle_caching( z );
8052 }
8053
8054 seen_cache_dirty |= build_vision_transparency_cache( zlev );
8055
8056 if( seen_cache_dirty ) {
8057 skew_vision_cache.clear();
8058 }
8059 // Initial value is illegal player position.
8060 const tripoint &p = g->u.pos();
8061 static tripoint player_prev_pos;
8062 if( seen_cache_dirty || player_prev_pos != p ) {
8063 build_seen_cache( p, zlev );
8064 player_prev_pos = p;
8065 }
8066 if( !skip_lightmap ) {
8067 generate_lightmap( zlev );
8068 }
8069}
bool fov_3d
3D FoV enabled/disabled.
void build_outside_cache(int zlev)
Definition: map.cpp:7752
void update_suspension_cache(const int &z)
Definition: map.cpp:7915
void do_vehicle_caching(int z)
Definition: map.cpp:8017
void build_seen_cache(const tripoint &origin, int target_z)
Calculates the Field Of View for the provided map from the given x, y coordinates.
Definition: lightmap.cpp:1224
lru_cache< point, char > skew_vision_cache
Cache of coordinate pairs recently checked for visibility.
Definition: map.h:1988
bool build_transparency_cache(int zlev)
Definition: lightmap.cpp:81
void generate_lightmap(int zlev)
Definition: lightmap.cpp:369
bool build_vision_transparency_cache(int zlev)
Definition: lightmap.cpp:165
bool seen_cache_dirty
Definition: map.h:299

References build_floor_cache(), build_outside_cache(), build_seen_cache(), build_transparency_cache(), build_vision_transparency_cache(), do_vehicle_caching(), fov_3d, g, generate_lightmap(), get_cache(), OVERMAP_DEPTH, OVERMAP_HEIGHT, level_cache::seen_cache_dirty, skew_vision_cache, update_suspension_cache(), and zlevels.

Referenced by game::do_turn(), game::draw(), game::look_around(), start_location::place_player(), game::start_game(), and game::update_map().

◆ build_obstacle_cache()

void map::build_obstacle_cache ( const tripoint start,
const tripoint end,
float(&)  obstacle_cache[MAPSIZE_X][MAPSIZE_Y] 
)

Definition at line 7806 of file map.cpp.

7808{
7809 const point min_submap{ std::max( 0, start.x / SEEX ), std::max( 0, start.y / SEEY ) };
7810 const point max_submap{
7811 std::min( my_MAPSIZE - 1, end.x / SEEX ), std::min( my_MAPSIZE - 1, end.y / SEEY ) };
7812 // Find and cache all the map obstacles.
7813 // For now setting obstacles to be extremely dense and fill their squares.
7814 // In future, scale effective obstacle density by the thickness of the obstacle.
7815 // Also consider modelling partial obstacles.
7816 // TODO: Support z-levels.
7817 for( int smx = min_submap.x; smx <= max_submap.x; ++smx ) {
7818 for( int smy = min_submap.y; smy <= max_submap.y; ++smy ) {
7819 const auto cur_submap = get_submap_at_grid( { smx, smy, start.z } );
7820
7821 // TODO: Init indices to prevent iterating over unused submap sections.
7822 for( int sx = 0; sx < SEEX; ++sx ) {
7823 for( int sy = 0; sy < SEEY; ++sy ) {
7824 const point sp( sx, sy );
7825 int ter_move = cur_submap->get_ter( sp ).obj().movecost;
7826 int furn_move = cur_submap->get_furn( sp ).obj().movecost;
7827 const int x = sx + smx * SEEX;
7828 const int y = sy + smy * SEEY;
7829 if( ter_move == 0 || furn_move < 0 || ter_move + furn_move == 0 ) {
7830 obstacle_cache[x][y] = 1000.0f;
7831 } else {
7832 obstacle_cache[x][y] = 0.0f;
7833 }
7834 }
7835 }
7836 }
7837 }
7838 VehicleList vehs = get_vehicles( start, end );
7839 const inclusive_cuboid<tripoint> bounds( start, end );
7840 // Cache all the vehicle stuff in one loop
7841 for( auto &v : vehs ) {
7842 for( const vpart_reference &vp : v.v->get_all_parts() ) {
7843 tripoint p = v.pos + vp.part().precalc[0];
7844 if( p.z != start.z ) {
7845 break;
7846 }
7847 if( !bounds.contains( p ) ) {
7848 continue;
7849 }
7850
7851 if( vp.obstacle_at_part() ) {
7852 obstacle_cache[p.x][p.y] = 1000.0f;
7853 }
7854 }
7855 }
7856}
VehicleList get_vehicles()
Definition: map.cpp:233
std::vector< wrapped_vehicle > VehicleList
Definition: map.h:85

References inclusive_cuboid< Tripoint, >::contains(), get_submap_at_grid(), get_vehicles(), my_MAPSIZE, SEEX, SEEY, sx, sy, tripoint::x, tripoint::y, and tripoint::z.

Referenced by explosion_handler::shrapnel().

◆ build_outside_cache()

void map::build_outside_cache ( int  zlev)

Definition at line 7752 of file map.cpp.

7753{
7754 auto &ch = get_cache( zlev );
7755 if( !ch.outside_cache_dirty ) {
7756 return;
7757 }
7758
7759 // Make a bigger cache to avoid bounds checking
7760 // We will later copy it to our regular cache
7761 const size_t padded_w = ( MAPSIZE_X ) + 2;
7762 const size_t padded_h = ( MAPSIZE_Y ) + 2;
7763 bool padded_cache[padded_w][padded_h];
7764
7765 auto &outside_cache = ch.outside_cache;
7766 if( zlev < 0 ) {
7767 std::uninitialized_fill_n(
7768 &outside_cache[0][0], ( MAPSIZE_X ) * ( MAPSIZE_Y ), false );
7769 return;
7770 }
7771
7772 std::uninitialized_fill_n(
7773 &padded_cache[0][0], padded_w * padded_h, true );
7774
7775 for( int smx = 0; smx < my_MAPSIZE; ++smx ) {
7776 for( int smy = 0; smy < my_MAPSIZE; ++smy ) {
7777 const auto cur_submap = get_submap_at_grid( { smx, smy, zlev } );
7778
7779 for( int sx = 0; sx < SEEX; ++sx ) {
7780 for( int sy = 0; sy < SEEY; ++sy ) {
7781 point sp( sx, sy );
7782 if( cur_submap->get_ter( sp ).obj().has_flag( TFLAG_INDOORS ) ||
7783 cur_submap->get_furn( sp ).obj().has_flag( TFLAG_INDOORS ) ) {
7784 const int x = sx + smx * SEEX;
7785 const int y = sy + smy * SEEY;
7786 // Add 1 to both coordinates, because we're operating on the padded cache
7787 for( int dx = 0; dx <= 2; dx++ ) {
7788 for( int dy = 0; dy <= 2; dy++ ) {
7789 padded_cache[x + dx][y + dy] = false;
7790 }
7791 }
7792 }
7793 }
7794 }
7795 }
7796 }
7797
7798 // Copy the padded cache back to the proper one, but with no padding
7799 for( int x = 0; x < SEEX * my_MAPSIZE; x++ ) {
7800 std::copy_n( &padded_cache[x + 1][1], SEEX * my_MAPSIZE, &outside_cache[x][0] );
7801 }
7802
7803 ch.outside_cache_dirty = false;
7804}

References get_cache(), get_submap_at_grid(), MAPSIZE_X, MAPSIZE_Y, my_MAPSIZE, SEEX, SEEY, sx, sy, and TFLAG_INDOORS.

Referenced by build_map_cache(), start_location::burn(), and start_location::prepare_map().

◆ build_seen_cache()

void map::build_seen_cache ( const tripoint origin,
int  target_z 
)
protected

Calculates the Field Of View for the provided map from the given x, y coordinates.

Returns a lightmap for a result where the values represent a percentage of fully lit.

A value equal to or below 0 means that cell is not in the field of view, whereas a value equal to or above 1 means that cell is in the field of view.

Parameters
originthe starting location
target_zZ-level to draw light map on

Definition at line 1224 of file lightmap.cpp.

1225{
1226 auto &map_cache = get_cache( target_z );
1227 float ( &transparency_cache )[MAPSIZE_X][MAPSIZE_Y] = map_cache.vision_transparency_cache;
1228 float ( &seen_cache )[MAPSIZE_X][MAPSIZE_Y] = map_cache.seen_cache;
1229 float ( &camera_cache )[MAPSIZE_X][MAPSIZE_Y] = map_cache.camera_cache;
1230
1231 constexpr float light_transparency_solid = LIGHT_TRANSPARENCY_SOLID;
1232 constexpr int map_dimensions = MAPSIZE_X * MAPSIZE_Y;
1233 std::uninitialized_fill_n(
1234 &camera_cache[0][0], map_dimensions, light_transparency_solid );
1235
1236 if( !fov_3d ) {
1237 for( int z = -OVERMAP_DEPTH; z <= OVERMAP_HEIGHT; z++ ) {
1238 auto &cur_cache = get_cache( z );
1239 if( z == target_z || cur_cache.seen_cache_dirty ) {
1240 std::uninitialized_fill_n(
1241 &cur_cache.seen_cache[0][0], map_dimensions, light_transparency_solid );
1242 cur_cache.seen_cache_dirty = false;
1243 }
1244
1245 if( z == target_z ) {
1246 seen_cache[origin.x][origin.y] = VISIBILITY_FULL;
1247 castLightAll<float, float, sight_calc, sight_check, update_light, accumulate_transparency>(
1248 seen_cache, transparency_cache, origin.xy(), 0 );
1249 }
1250 }
1251 } else {
1252 // Cache the caches (pointers to them)
1253 array_of_grids_of<const float> transparency_caches;
1254 array_of_grids_of<float> seen_caches;
1255 array_of_grids_of<const bool> floor_caches;
1256 for( int z = -OVERMAP_DEPTH; z <= OVERMAP_HEIGHT; z++ ) {
1257 auto &cur_cache = get_cache( z );
1258 transparency_caches[z + OVERMAP_DEPTH] = &cur_cache.vision_transparency_cache;
1259 seen_caches[z + OVERMAP_DEPTH] = &cur_cache.seen_cache;
1260 floor_caches[z + OVERMAP_DEPTH] = &cur_cache.floor_cache;
1261 std::uninitialized_fill_n(
1262 &cur_cache.seen_cache[0][0], map_dimensions, light_transparency_solid );
1263 cur_cache.seen_cache_dirty = false;
1264 }
1265 if( origin.z == target_z ) {
1267 }
1269 seen_caches, transparency_caches, floor_caches, origin, 0, 1.0 );
1270 }
1271
1273 if( !vp ) {
1274 return;
1275 }
1276 vehicle *const veh = &vp->vehicle();
1277
1278 // We're inside a vehicle. Do mirror calculations.
1279 std::vector<int> mirrors;
1280 // Do all the sight checks first to prevent fake multiple reflection
1281 // from happening due to mirrors becoming visible due to processing order.
1282 // Cameras are also handled here, so that we only need to get through all vehicle parts once
1283 int cam_control = -1;
1284 for( const vpart_reference &vp : veh->get_avail_parts( VPFLAG_EXTENDS_VISION ) ) {
1285 const tripoint mirror_pos = vp.pos();
1286 // We can utilize the current state of the seen cache to determine
1287 // if the player can see the mirror from their position.
1288 if( !vp.info().has_flag( "CAMERA" ) &&
1289 seen_cache[mirror_pos.x][mirror_pos.y] < LIGHT_TRANSPARENCY_SOLID + 0.1 ) {
1290 continue;
1291 } else if( !vp.info().has_flag( "CAMERA_CONTROL" ) ) {
1292 mirrors.emplace_back( static_cast<int>( vp.part_index() ) );
1293 } else {
1294 if( square_dist( origin, mirror_pos ) <= 1 && veh->camera_on ) {
1295 cam_control = static_cast<int>( vp.part_index() );
1296 }
1297 }
1298 }
1299
1300 for( int mirror : mirrors ) {
1301 bool is_camera = veh->part_info( mirror ).has_flag( "CAMERA" );
1302 if( is_camera && cam_control < 0 ) {
1303 continue; // Player not at camera control, so cameras don't work
1304 }
1305
1306 const tripoint mirror_pos = veh->global_part_pos3( mirror );
1307
1308 // Determine how far the light has already traveled so mirrors
1309 // don't cheat the light distance falloff.
1310 int offsetDistance;
1311 if( !is_camera ) {
1312 offsetDistance = rl_dist( origin, mirror_pos );
1313 } else {
1314 offsetDistance = 60 - veh->part_info( mirror ).bonus *
1315 veh->part( mirror ).hp() / veh->part_info( mirror ).durability;
1316 camera_cache[mirror_pos.x][mirror_pos.y] = LIGHT_TRANSPARENCY_OPEN_AIR;
1317 }
1318
1319 // TODO: Factor in the mirror facing and only cast in the
1320 // directions the player's line of sight reflects to.
1321 //
1322 // The naive solution of making the mirrors act like a second player
1323 // at an offset appears to give reasonable results though.
1324 castLightAll<float, float, sight_calc, sight_check, update_light, accumulate_transparency>(
1325 camera_cache, transparency_cache, mirror_pos.xy(), offsetDistance );
1326 }
1327}
vehicle_part_with_feature_range< std::string > get_avail_parts(std::string feature) const
Yields a range of parts of this vehicle that each have the given feature and are available: not broke...
Definition: vehicle.cpp:2680
bool camera_on
Definition: vehicle.h:1976
const vpart_info & part_info(int index, bool include_removed=false) const
Definition: vehicle.cpp:1137
int bonus
seatbelt (str), muffler (%), horn (vol), light (intensity), recharing (power)
Definition: veh_type.h:269
bool has_flag(const std::string &flag) const
Definition: veh_type.h:336
int durability
Maximum damage part can sustain before being destroyed.
Definition: veh_type.h:173
template void cast_zlight< float, sight_calc, sight_check, accumulate_transparency >(const array_of_grids_of< float > &output_caches, const array_of_grids_of< const float > &input_arrays, const array_of_grids_of< const bool > &floor_caches, const tripoint &origin, int offset_distance, float numerator)
static constexpr float VISIBILITY_FULL
Definition: lightmap.h:39
std::array< T(*)[MAPSIZE_X][MAPSIZE_Y], OVERMAP_LAYERS > array_of_grids_of
int hp() const
current part health with range [0,durability]
@ VPFLAG_EXTENDS_VISION
Definition: veh_type.h:68

References vpart_info::bonus, vehicle::camera_on, cast_zlight< float, sight_calc, sight_check, accumulate_transparency >(), vpart_info::durability, fov_3d, vehicle::get_avail_parts(), get_cache(), vehicle::global_part_pos3(), vpart_info::has_flag(), vehicle_part::hp(), LIGHT_TRANSPARENCY_OPEN_AIR, LIGHT_TRANSPARENCY_SOLID, MAPSIZE_X, MAPSIZE_Y, OVERMAP_DEPTH, OVERMAP_HEIGHT, vehicle::part(), vehicle::part_info(), rl_dist(), level_cache::seen_cache, square_dist(), veh_at(), VISIBILITY_FULL, VPFLAG_EXTENDS_VISION, tripoint::x, tripoint::xy(), and tripoint::y.

Referenced by build_map_cache().

◆ build_sunlight_cache()

void map::build_sunlight_cache ( int  pzlev)
protected

Definition at line 218 of file lightmap.cpp.

219{
220 const int zlev_min = zlevels ? -OVERMAP_DEPTH : pzlev;
221 // Start at the topmost populated zlevel to avoid unnecessary raycasting
222 // Plus one zlevel to prevent clipping inside structures
223 const int zlev_max = zlevels
225 std::min( OVERMAP_HEIGHT, pzlev + 1 ),
227 : pzlev;
228
229 // true if all previous z-levels are fully transparent to light (no floors, transparency >= air)
230 bool fully_outside = true;
231
232 // true if no light reaches this level, i.e. there were no lit tiles on the above level (light level <= inside_light_level)
233 bool fully_inside = false;
234
235 // fully_outside and fully_inside define following states:
236 // initially: fully_outside=true, fully_inside=false (fast fill)
237 // ↓
238 // when first obstacles occur: fully_outside=false, fully_inside=false (slow quadrant logic)
239 // ↓
240 // when fully below ground: fully_outside=false, fully_inside=true (fast fill)
241
242 // Iterate top to bottom because sunlight cache needs to construct in that order.
243 for( int zlev = zlev_max; zlev >= zlev_min; zlev-- ) {
244
245 level_cache &map_cache = get_cache( zlev );
246 auto &lm = map_cache.lm;
247 // Grab illumination at ground level.
248 const float outside_light_level = g->natural_light_level( 0 );
249 // TODO: if zlev < 0 is open to sunlight, this won't calculate correct light, but neither does g->natural_light_level()
250 const float inside_light_level = ( zlev >= 0 && outside_light_level > LIGHT_SOURCE_BRIGHT ) ?
252 // Handling when z-levels are disabled is based on whether a tile is considered "outside".
253 if( !zlevels ) {
254 const auto &outside_cache = map_cache.outside_cache;
255 for( int x = 0; x < MAPSIZE_X; x++ ) {
256 for( int y = 0; y < MAPSIZE_Y; y++ ) {
257 if( outside_cache[x][y] ) {
258 lm[x][y].fill( outside_light_level );
259 } else {
260 lm[x][y].fill( inside_light_level );
261 }
262 }
263 }
264 continue;
265 }
266
267 // all light was blocked before
268 if( fully_inside ) {
269 std::fill_n( &lm[0][0], MAPSIZE_X * MAPSIZE_Y, four_quadrants( inside_light_level ) );
270 continue;
271 }
272
273 // If there were no obstacles before this level, just apply weather illumination since there's no opportunity
274 // for light to be blocked.
275 if( fully_outside ) {
276 //fill with full light
277 std::fill_n( &lm[0][0], MAPSIZE_X * MAPSIZE_Y, four_quadrants( outside_light_level ) );
278
279 const auto &this_floor_cache = map_cache.floor_cache;
280 const auto &this_transparency_cache = map_cache.transparency_cache;
281 fully_inside = true; // recalculate
282
283 for( int x = 0; x < MAPSIZE_X; ++x ) {
284 for( int y = 0; y < MAPSIZE_Y; ++y ) {
285 // && semantics below is important, we want to skip the evaluation if possible, do not replace with &=
286
287 // fully_outside stays true if tile is transparent and there is no floor
288 fully_outside = fully_outside && this_transparency_cache[x][y] >= LIGHT_TRANSPARENCY_OPEN_AIR
289 && !this_floor_cache[x][y];
290 // fully_inside stays true if tile is opaque OR there is floor
291 fully_inside = fully_inside && ( this_transparency_cache[x][y] <= LIGHT_TRANSPARENCY_SOLID ||
292 this_floor_cache[x][y] );
293 }
294 }
295 continue;
296 }
297
298 // Replace this with a calculated shift based on time of day and date.
299 // At first compress the angle such that it takes no more than one tile of shift per level.
300 // To exceed that, we'll have to handle casting light from the side instead of the top.
301 point offset;
302 const level_cache &prev_map_cache = get_cache_ref( zlev + 1 );
303 const auto &prev_lm = prev_map_cache.lm;
304 const auto &prev_transparency_cache = prev_map_cache.transparency_cache;
305 const auto &prev_floor_cache = prev_map_cache.floor_cache;
306 const auto &outside_cache = map_cache.outside_cache;
307 const float sight_penalty = get_weather().weather_id->sight_penalty;
308 // TODO: Replace these with a lookup inside the four_quadrants class.
309 constexpr std::array<point, 5> cardinals = {
311 };
312 constexpr std::array<std::array<quadrant, 2>, 5> dir_quadrants = {{
318 }
319 };
320
321 fully_inside = true; // recalculate
322
323 // Fall back to minimal light level if we don't find anything.
324 std::fill_n( &lm[0][0], MAPSIZE_X * MAPSIZE_Y, four_quadrants( inside_light_level ) );
325
326 for( int x = 0; x < MAPSIZE_X; ++x ) {
327 for( int y = 0; y < MAPSIZE_Y; ++y ) {
328 // Check center, then four adjacent cardinals.
329 for( int i = 0; i < 5; ++i ) {
330 int prev_x = x + offset.x + cardinals[i].x;
331 int prev_y = y + offset.y + cardinals[i].y;
332 bool inbounds = prev_x >= 0 && prev_x < MAPSIZE_X &&
333 prev_y >= 0 && prev_y < MAPSIZE_Y;
334
335 if( !inbounds ) {
336 continue;
337 }
338
339 float prev_light_max;
340 float prev_transparency = prev_transparency_cache[prev_x][prev_y];
341 // This is pretty gross, this cancels out the per-tile transparency effect
342 // derived from weather.
343 if( outside_cache[x][y] ) {
344 prev_transparency /= sight_penalty;
345 }
346
347 if( prev_transparency > LIGHT_TRANSPARENCY_SOLID &&
348 !prev_floor_cache[prev_x][prev_y] &&
349 ( prev_light_max = prev_lm[prev_x][prev_y].max() ) > 0.0 ) {
350 const float light_level = clamp( prev_light_max * LIGHT_TRANSPARENCY_OPEN_AIR / prev_transparency,
351 inside_light_level, prev_light_max );
352
353 if( i == 0 ) {
354 lm[x][y].fill( light_level );
355 fully_inside &= light_level <= inside_light_level;
356 break;
357 } else {
358 fully_inside &= light_level <= inside_light_level;
359 lm[x][y][dir_quadrants[i][0]] = light_level;
360 lm[x][y][dir_quadrants[i][1]] = light_level;
361 }
362 }
363 }
364 }
365 }
366 }
367}
constexpr T clamp(const T &val, const T &min, const T &max)
Clamp first argument so that it is no lower than second and no higher than third.
Definition: cata_utility.h:145
int calc_max_populated_zlev()
Caclulate the greatest populated zlevel in the loaded submaps and save in the level cache.
Definition: map.cpp:8737
weather_type_id weather_id
Definition: weather.h:193
weather_manager & get_weather()
Definition: weather.cpp:64
static constexpr float LIGHT_AMBIENT_DIM
Definition: lightmap.h:16
bool floor_cache[MAPSIZE_X][MAPSIZE_Y]
Definition: map.h:318
bool outside_cache[MAPSIZE_X][MAPSIZE_Y]
Definition: map.h:312
float sight_penalty
Definition: weather_type.h:111

References calc_max_populated_zlev(), clamp(), level_cache::floor_cache, g, get_cache(), get_cache_ref(), get_weather(), inbounds(), LIGHT_AMBIENT_DIM, LIGHT_AMBIENT_LOW, LIGHT_SOURCE_BRIGHT, LIGHT_TRANSPARENCY_OPEN_AIR, LIGHT_TRANSPARENCY_SOLID, level_cache::lm, MAPSIZE_X, MAPSIZE_Y, NE, NW, level_cache::outside_cache, OVERMAP_DEPTH, OVERMAP_HEIGHT, point_east, point_north, point_south, point_west, point_zero, SE, weather_type::sight_penalty, SW, level_cache::transparency_cache, weather_manager::weather_id, point::x, point::y, and zlevels.

Referenced by generate_lightmap().

◆ build_transparency_cache()

bool map::build_transparency_cache ( int  zlev)
protected

Definition at line 81 of file lightmap.cpp.

82{
83 auto &map_cache = get_cache( zlev );
84 auto &transparency_cache = map_cache.transparency_cache;
85 auto &outside_cache = map_cache.outside_cache;
86
87 if( map_cache.transparency_cache_dirty.none() ) {
88 return false;
89 }
90
91 // if true, all submaps are invalid (can use batch init)
92 bool rebuild_all = map_cache.transparency_cache_dirty.all();
93
94 if( rebuild_all ) {
95 // Default to just barely not transparent.
96 std::uninitialized_fill_n( &transparency_cache[0][0], MAPSIZE_X * MAPSIZE_Y,
97 static_cast<float>( LIGHT_TRANSPARENCY_OPEN_AIR ) );
98 }
99
100 const float sight_penalty = get_weather().weather_id->sight_penalty;
101
102 // Traverse the submaps in order
103 for( int smx = 0; smx < my_MAPSIZE; ++smx ) {
104 for( int smy = 0; smy < my_MAPSIZE; ++smy ) {
105 const auto cur_submap = get_submap_at_grid( {smx, smy, zlev} );
106
107 const point sm_offset = sm_to_ms_copy( point( smx, smy ) );
108
109 if( !rebuild_all && !map_cache.transparency_cache_dirty[smx * MAPSIZE + smy] ) {
110 continue;
111 }
112
113 // calculates transparency of a single tile
114 // x,y - coords in map local coords
115 auto calc_transp = [&]( const point & p ) {
116 const point sp = p - sm_offset;
117 float value = LIGHT_TRANSPARENCY_OPEN_AIR;
118
119 if( !( cur_submap->get_ter( sp ).obj().transparent &&
120 cur_submap->get_furn( sp ).obj().transparent ) ) {
122 }
123 if( outside_cache[p.x][p.y] ) {
124 // FIXME: Places inside vehicles haven't been marked as
125 // inside yet so this is incorrectly penalising for
126 // weather in vehicles.
127 value *= sight_penalty;
128 }
129 for( const auto &fld : cur_submap->get_field( sp ) ) {
130 const field_entry &cur = fld.second;
131 if( cur.is_transparent() ) {
132 continue;
133 }
134 // Fields are either transparent or not, however we want some to be translucent
135 value = value * cur.translucency();
136 }
137 // TODO: [lightmap] Have glass reduce light as well
138 return value;
139 };
140
141 if( cur_submap->is_uniform ) {
142 float value = calc_transp( sm_offset );
143 // if rebuild_all==true all values were already set to LIGHT_TRANSPARENCY_OPEN_AIR
144 if( !rebuild_all || value != LIGHT_TRANSPARENCY_OPEN_AIR ) {
145 for( int sx = 0; sx < SEEX; ++sx ) {
146 // init all sy indices in one go
147 std::uninitialized_fill_n( &transparency_cache[sm_offset.x + sx][sm_offset.y], SEEY, value );
148 }
149 }
150 } else {
151 for( int sx = 0; sx < SEEX; ++sx ) {
152 const int x = sx + sm_offset.x;
153 for( int sy = 0; sy < SEEY; ++sy ) {
154 const int y = sy + sm_offset.y;
155 transparency_cache[x][y] = calc_transp( { x, y } );
156 }
157 }
158 }
159 }
160 }
161 map_cache.transparency_cache_dirty.reset();
162 return true;
163}
An active or passive effect existing on a tile.
Definition: field.h:20
bool is_transparent() const
Definition: field.cpp:84
float translucency() const
Definition: field.cpp:79

References get_cache(), get_submap_at_grid(), get_weather(), field_entry::is_transparent(), LIGHT_TRANSPARENCY_OPEN_AIR, LIGHT_TRANSPARENCY_SOLID, MAPSIZE, MAPSIZE_X, MAPSIZE_Y, my_MAPSIZE, SEEX, SEEY, weather_type::sight_penalty, sm_to_ms_copy(), sx, sy, field_entry::translucency(), and weather_manager::weather_id.

Referenced by build_map_cache().

◆ build_vision_transparency_cache()

bool map::build_vision_transparency_cache ( int  zlev)
protected

Definition at line 165 of file lightmap.cpp.

166{
167 auto &map_cache = get_cache( zlev );
168 auto &transparency_cache = map_cache.transparency_cache;
169 auto &vision_transparency_cache = map_cache.vision_transparency_cache;
170
171 memcpy( &vision_transparency_cache, &transparency_cache, sizeof( transparency_cache ) );
172
173 const tripoint &p = g->u.pos();
174
175 if( p.z != zlev ) {
176 return false;
177 }
178
179 bool dirty = false;
180
181 bool is_crouching = g->u.movement_mode_is( CMM_CROUCH );
182 for( const tripoint &loc : points_in_radius( p, 1 ) ) {
183 if( loc == p ) {
184 // The tile player is standing on should always be visible
185 vision_transparency_cache[p.x][p.y] = LIGHT_TRANSPARENCY_OPEN_AIR;
186 } else if( is_crouching && coverage( loc ) >= 30 ) {
187 // If we're crouching behind an obstacle, we can't see past it.
188 vision_transparency_cache[loc.x][loc.y] = LIGHT_TRANSPARENCY_SOLID;
189 dirty = true;
190 }
191 }
192
193 return dirty;
194}
@ CMM_CROUCH
Definition: character.h:99
int coverage(const tripoint &p) const
Returns coverage value of the tile.
Definition: map.cpp:6210

References CMM_CROUCH, coverage(), g, get_cache(), LIGHT_TRANSPARENCY_OPEN_AIR, LIGHT_TRANSPARENCY_SOLID, points_in_radius(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by build_map_cache().

◆ burn_body_part()

int map::burn_body_part ( player u,
field_entry cur,
body_part  bp,
int  scale 
)
private

Definition at line 124 of file map_field.cpp.

125{
126 int total_damage = 0;
127 const int intensity = cur.get_field_intensity();
128 const int damage = rng( 1, ( scale + intensity ) / 2 );
129 // A bit ugly, but better than being annoyed by acid when in hazmat
130 if( u.get_armor_type( DT_ACID, convert_bp( bp ) ) < damage ) {
131 const dealt_damage_instance ddi = u.deal_damage( nullptr, convert_bp( bp ).id(),
132 damage_instance( DT_ACID, damage ) );
133 total_damage += ddi.total_damage();
134 }
135 // Represents acid seeping in rather than being splashed on
137 1 + intensity ) ), bp, 0 );
138 return total_damage;
139}
units::quantity< V, B > rng(const units::quantity< V, B > &min, const units::quantity< V, B > &max)
Definition: artifact.cpp:32
const bodypart_str_id & convert_bp(body_part bp)
Returns the new id for old token.
Definition: bodypart.cpp:185
dealt_damage_instance deal_damage(Creature *source, bodypart_id bp, const damage_instance &d) override
Calls Creature::deal_damage and handles damaged effects (waking up, etc.)
Definition: character.cpp:8469
int get_armor_type(damage_type dt, bodypart_id bp) const override
Returns overall resistance to given type on the bod part.
Definition: character.cpp:6997
bool add_env_effect(const efftype_id &eff_id, body_part vector, int strength, const time_duration &dur, body_part bp=num_bp, int intensity=1, bool force=false)
Gives chance to save via environmental resist, returns false if resistance was successful.
Definition: creature.cpp:1109
int get_field_intensity() const
Definition: field.cpp:121
static constexpr time_duration from_turns(const T t)
Named constructors to get a duration representing a multiple of the named time units.
Definition: calendar.h:204
@ DT_ACID
Definition: damage.h:26
static const efftype_id effect_corroding("corroding")
int total_damage() const
Definition: damage.cpp:180

References Creature::add_env_effect(), convert_bp(), Character::deal_damage(), DT_ACID, effect_corroding, time_duration::from_turns(), Character::get_armor_type(), field_entry::get_field_intensity(), rng(), and dealt_damage_instance::total_damage().

Referenced by player_in_field().

◆ calc_max_populated_zlev()

int map::calc_max_populated_zlev ( )
private

Caclulate the greatest populated zlevel in the loaded submaps and save in the level cache.

fills the map::max_populated_zlev and returns it

Returns
max_populated_zlev value

Definition at line 8737 of file map.cpp.

8738{
8739 // cache is filled and valid, skip recalculation
8741 return max_populated_zlev->second;
8742 }
8743
8744 // We'll assume ground level is populated
8745 int max_z = 0;
8746
8747 for( int sz = 1; sz <= OVERMAP_HEIGHT; sz++ ) {
8748 bool level_done = false;
8749 for( int sx = 0; sx < my_MAPSIZE; sx++ ) {
8750 for( int sy = 0; sy < my_MAPSIZE; sy++ ) {
8751 const submap *sm = get_submap_at_grid( tripoint( sx, sy, sz ) );
8752 if( !sm->is_uniform ) {
8753 max_z = sz;
8754 level_done = true;
8755 break;
8756 }
8757 }
8758 if( level_done ) {
8759 break;
8760 }
8761 }
8762 }
8763
8764 max_populated_zlev = std::pair<tripoint, int>( get_abs_sub(), max_z );
8765 return max_z;
8766}
cata::optional< std::pair< tripoint, int > > max_populated_zlev
Definition: map.h:2007
tripoint get_abs_sub() const
return abs_sub
Definition: map.cpp:8089

References get_abs_sub(), get_submap_at_grid(), max_populated_zlev, my_MAPSIZE, OVERMAP_HEIGHT, coords::sm, sx, and sy.

Referenced by build_sunlight_cache().

◆ can_move_furniture()

bool map::can_move_furniture ( const tripoint pos,
player p = nullptr 
)
Strength determines what furniture the player can move

Definition at line 1440 of file map.cpp.

1441{
1442 if( !p ) {
1443 return false;
1444 }
1445 const furn_t &furniture_type = furn( pos ).obj();
1446 int required_str = furniture_type.move_str_req;
1447
1448 // Object can not be moved (or nothing there)
1449 if( required_str < 0 ) {
1450 return false;
1451 }
1452
1453 ///\EFFECT_STR determines what furniture the player can move
1454 int adjusted_str = p->str_cur;
1455 if( p->is_mounted() ) {
1456 auto mons = p->mounted_creature.get();
1457 if( mons->has_flag( MF_RIDEABLE_MECH ) && mons->mech_str_addition() != 0 ) {
1458 adjusted_str = mons->mech_str_addition();
1459 }
1460 }
1461 return adjusted_str >= required_str;
1462}
int str_cur
Definition: character.h:304
bool is_mounted() const
Definition: character.cpp:1138
shared_ptr_fast< monster > mounted_creature
Definition: character.h:1622
@ MF_RIDEABLE_MECH
Definition: mtype.h:115
int move_str_req
Definition: mapdata.h:505

References furn(), Character::is_mounted(), MF_RIDEABLE_MECH, Character::mounted_creature, furn_t::move_str_req, int_id< T >::obj(), wrapped_vehicle::pos, and Character::str_cur.

Referenced by grab().

◆ can_put_items() [1/2]

bool map::can_put_items ( const point p) const
inline

Definition at line 943 of file map.h.

943 {
944 return can_put_items( tripoint( p, abs_sub.z ) );
945 }
bool can_put_items(const tripoint &p) const
Definition: map.cpp:2293

References abs_sub, can_put_items(), and tripoint::z.

◆ can_put_items() [2/2]

bool map::can_put_items ( const tripoint p) const

Definition at line 2293 of file map.cpp.

2294{
2295 if( can_put_items_ter_furn( p ) ) {
2296 return true;
2297 }
2298 const optional_vpart_position vp = veh_at( p );
2299 return static_cast<bool>( vp.part_with_feature( "CARGO", true ) );
2300}
bool can_put_items_ter_furn(const tripoint &p) const
Definition: map.cpp:2302

References can_put_items_ter_furn(), optional_vpart_position::part_with_feature(), and veh_at().

Referenced by can_put_items(), complete_construction(), haul(), and game::place_player().

◆ can_put_items_ter_furn() [1/2]

bool map::can_put_items_ter_furn ( const point p) const
inline

Definition at line 948 of file map.h.

948 {
950 }

References abs_sub, can_put_items_ter_furn(), and tripoint::z.

◆ can_put_items_ter_furn() [2/2]

bool map::can_put_items_ter_furn ( const tripoint p) const

◆ can_see_trap_at()

bool map::can_see_trap_at ( const tripoint p,
const Character c 
) const

See trap::can_see, which is called for the trap here.

Definition at line 5110 of file map.cpp.

5111{
5112 return tr_at( p ).can_see( p, c );
5113}
const trap & tr_at(const tripoint &p) const
Definition: map.cpp:5115
constexpr double c
Definition: magic.cpp:1032
bool can_see(const tripoint &pos, const Character &p) const
Can player/npc p see this kind of trap, either by their memory (they known there is the trap) or by t...
Definition: trap.cpp:223

References c, trap::can_see(), and tr_at().

Referenced by can_examine_at(), and vehicle::autodrive_controller::check_drivable().

◆ check_and_set_seen_cache()

bool map::check_and_set_seen_cache ( const tripoint p) const
inline

Definition at line 474 of file map.h.

474 {
475 std::bitset<MAPSIZE_X *MAPSIZE_Y> &memory_seen_cache =
477 if( !memory_seen_cache[ static_cast<size_t>( p.x + p.y * MAPSIZE_Y ) ] ) {
478 memory_seen_cache.set( static_cast<size_t>( p.x + p.y * MAPSIZE_Y ) );
479 return true;
480 }
481 return false;
482 }
std::bitset< MAPSIZE_X *MAPSIZE_Y > map_memory_seen_cache
Definition: map.h:339

References get_cache(), level_cache::map_memory_seen_cache, MAPSIZE_Y, tripoint::x, tripoint::y, and tripoint::z.

Referenced by draw_maptile().

◆ check_seen_cache()

bool map::check_seen_cache ( const tripoint p) const
inline

Definition at line 469 of file map.h.

469 {
470 std::bitset<MAPSIZE_X *MAPSIZE_Y> &memory_seen_cache =
472 return !memory_seen_cache[ static_cast<size_t>( p.x + p.y * MAPSIZE_Y ) ];
473 }

References get_cache(), level_cache::map_memory_seen_cache, MAPSIZE_Y, tripoint::x, tripoint::y, and tripoint::z.

◆ check_submap_active_item_consistency()

std::vector< tripoint > map::check_submap_active_item_consistency ( )

Definition at line 4533 of file map.cpp.

4534{
4535 std::vector<tripoint> result;
4536 for( int z = -OVERMAP_DEPTH; z < OVERMAP_HEIGHT; ++z ) {
4537 for( int x = 0; x < MAPSIZE; ++x ) {
4538 for( int y = 0; y < MAPSIZE; ++y ) {
4539 tripoint p( x, y, z );
4540 submap *s = get_submap_at_grid( p );
4541 bool has_active_items = !s->active_items.get().empty();
4542 bool map_has_active_items = submaps_with_active_items.count( p + abs_sub.xy() );
4543 if( has_active_items != map_has_active_items ) {
4544 result.push_back( p + abs_sub.xy() );
4545 }
4546 }
4547 }
4548 }
4549 for( const tripoint &p : submaps_with_active_items ) {
4550 tripoint rel = p - abs_sub.xy();
4552 if( !map.contains( rel.xy() ) ) {
4553 result.push_back( p );
4554 }
4555 }
4556 return result;
4557}
std::vector< item_reference > get()
Returns a vector of all cached active item references.
Manage and cache data about a part of the map.
Definition: map.h:372

References abs_sub, submap::active_items, active_item_cache::get(), get_submap_at_grid(), map(), MAPSIZE, OVERMAP_DEPTH, OVERMAP_HEIGHT, point_zero, submaps_with_active_items, and tripoint::xy().

◆ check_vehicle_zones()

bool map::check_vehicle_zones ( int  zlev)

Definition at line 924 of file map.cpp.

925{
926 for( auto veh : get_cache( zlev ).zone_vehicles ) {
927 if( veh->zones_dirty ) {
928 return true;
929 }
930 }
931 return false;
932}

References get_cache().

Referenced by activity_on_turn_move_loot(), talk_function::basecamp_mission(), basecamp::distribute_food(), find_auto_consume(), basecamp::place_results(), and basecamp::validate_sort_points().

◆ clear_path()

bool map::clear_path ( const tripoint f,
const tripoint t,
int  range,
int  cost_min,
int  cost_max 
) const

Check whether there's a direct line of sight between F and T with the additional movecost restraints.

Checks two things:

  1. The sees() algorithm between F and T
  2. That moving over the line of sight would have a move_cost between cost_min and cost_max.

Definition at line 6360 of file map.cpp.

6362{
6363 // Ugly `if` for now
6364 if( !fov_3d && f.z != t.z ) {
6365 return false;
6366 }
6367
6368 if( f.z == t.z ) {
6369 if( ( range >= 0 && range < rl_dist( f.xy(), t.xy() ) ) ||
6370 !inbounds( t ) ) {
6371 return false; // Out of range!
6372 }
6373 bool is_clear = true;
6374 bresenham( f.xy(), t.xy(), 0,
6375 [this, &is_clear, cost_min, cost_max, &t]( const point & new_point ) {
6376 // Exit before checking the last square, it's still reachable even if it is an obstacle.
6377 if( new_point.x == t.x && new_point.y == t.y ) {
6378 return false;
6379 }
6380
6381 const int cost = this->move_cost( new_point );
6382 if( cost < cost_min || cost > cost_max ) {
6383 is_clear = false;
6384 return false;
6385 }
6386 return true;
6387 } );
6388 return is_clear;
6389 }
6390
6391 if( ( range >= 0 && range < rl_dist( f, t ) ) ||
6392 !inbounds( t ) ) {
6393 return false; // Out of range!
6394 }
6395 bool is_clear = true;
6396 tripoint last_point = f;
6397 bresenham( f, t, 0, 0,
6398 [this, &is_clear, cost_min, cost_max, t, &last_point]( const tripoint & new_point ) {
6399 // Exit before checking the last square, it's still reachable even if it is an obstacle.
6400 if( new_point == t ) {
6401 return false;
6402 }
6403
6404 // We have to check a weird case where the move is both vertical and horizontal
6405 if( new_point.z == last_point.z ) {
6406 const int cost = move_cost( new_point );
6407 if( cost < cost_min || cost > cost_max ) {
6408 is_clear = false;
6409 return false;
6410 }
6411 } else {
6412 bool this_clear = false;
6413 const int max_z = std::max( new_point.z, last_point.z );
6414 if( !has_floor_or_support( {new_point.xy(), max_z} ) ) {
6415 const int cost = move_cost( {new_point.xy(), last_point.z} );
6416 if( cost > cost_min && cost < cost_max ) {
6417 this_clear = true;
6418 }
6419 }
6420
6421 if( !this_clear && has_floor_or_support( {last_point.xy(), max_z} ) ) {
6422 const int cost = move_cost( {last_point.xy(), new_point.z} );
6423 if( cost > cost_min && cost < cost_max ) {
6424 this_clear = true;
6425 }
6426 }
6427
6428 if( !this_clear ) {
6429 is_clear = false;
6430 return false;
6431 }
6432 }
6433
6434 last_point = new_point;
6435 return true;
6436 } );
6437 return is_clear;
6438}
bool has_floor_or_support(const tripoint &p) const
Definition: map.cpp:2034
int move_cost(const tripoint &p, const vehicle *ignored_vehicle=nullptr) const
Calculate the cost to move past the tile at p.
Definition: map.cpp:1775
void bresenham(const point &p1, const point &p2, int t, const std::function< bool(const point &)> &interact)
The actual Bresenham algorithm in 2D and 3D, everything else should call these and pass in an interac...
Definition: line.cpp:24

References bresenham(), fov_3d, inbounds(), rl_dist(), tripoint::xy(), and tripoint::z.

Referenced by find_best_fire(), player::get_eligible_containers_for_crafting(), has_clear_path_to_pickup_items(), points_for_gas_cloud(), process_fields_in_submap(), game::start_game(), and vehicle_selector::vehicle_selector().

◆ clear_spawns()

void map::clear_spawns ( )

Definition at line 7580 of file map.cpp.

7581{
7582 for( auto &smap : grid ) {
7583 smap->spawns.clear();
7584 }
7585}

References grid.

Referenced by defense_game::init_map().

◆ clear_traps()

void map::clear_traps ( )

Definition at line 7587 of file map.cpp.

7588{
7589 for( auto &smap : grid ) {
7590 for( int x = 0; x < SEEX; x++ ) {
7591 for( int y = 0; y < SEEY; y++ ) {
7592 const point p( x, y );
7593 smap->set_trap( p, tr_null );
7594 }
7595 }
7596 }
7597
7598 // Forget about all trap locations.
7599 for( auto &i : traplocs ) {
7600 i.clear();
7601 }
7602}

References grid, SEEX, SEEY, tr_null, and traplocs.

Referenced by defense_game::init_map().

◆ clear_vehicle_cache()

void map::clear_vehicle_cache ( )

Definition at line 309 of file map.cpp.

310{
311 const int zmin = zlevels ? -OVERMAP_DEPTH : abs_sub.z;
312 const int zmax = zlevels ? OVERMAP_HEIGHT : abs_sub.z;
313 for( int zlev = zmin; zlev <= zmax; zlev++ ) {
314 level_cache &ch = get_cache( zlev );
315 while( !ch.veh_cached_parts.empty() ) {
316 const auto part = ch.veh_cached_parts.begin();
317 const auto &p = part->first;
318 if( inbounds( p ) ) {
319 ch.veh_exists_at[p.x][p.y] = false;
320 }
321 ch.veh_cached_parts.erase( part );
322 }
323 ch.veh_in_active_range = false;
324 }
325}

References abs_sub, get_cache(), inbounds(), OVERMAP_DEPTH, OVERMAP_HEIGHT, level_cache::veh_cached_parts, level_cache::veh_exists_at, level_cache::veh_in_active_range, tripoint::z, and zlevels.

Referenced by editmap::mapgen_preview(), game::place_player_overmap(), reset_vehicle_cache(), rotate(), shift(), and game::vertical_shift().

◆ clear_vehicle_list()

void map::clear_vehicle_list ( int  zlev)

Definition at line 327 of file map.cpp.

328{
329 auto &ch = get_cache( zlev );
330 ch.vehicle_list.clear();
331 ch.zone_vehicles.clear();
332
334}

References get_cache(), and last_full_vehicle_list_dirty.

Referenced by editmap::mapgen_preview(), editmap::mapgen_veh_destroy(), game::place_player_overmap(), rotate(), and shift().

◆ clear_vehicle_point_from_cache()

void map::clear_vehicle_point_from_cache ( vehicle veh,
const tripoint pt 
)

Definition at line 291 of file map.cpp.

292{
293 if( veh == nullptr ) {
294 debugmsg( "Tried to clear null vehicle from cache" );
295 return;
296 }
297
298 level_cache &ch = get_cache( pt.z );
299 if( inbounds( pt ) ) {
300 ch.veh_exists_at[pt.x][pt.y] = false;
301 }
302 auto it = ch.veh_cached_parts.find( pt );
303 if( it != ch.veh_cached_parts.end() && it->second.first == veh ) {
304 ch.veh_cached_parts.erase( it );
305 }
306
307}

References debugmsg, get_cache(), inbounds(), level_cache::veh_cached_parts, level_cache::veh_exists_at, tripoint::x, tripoint::y, and tripoint::z.

Referenced by vehicle::advance_precalc_mounts(), veh_interact::complete_vehicle(), and vehicle::part_removal_cleanup().

◆ climb_difficulty()

int map::climb_difficulty ( const tripoint p) const

Checks 3x3 block centered on p for terrain to climb.

Returns
Difficulty of climbing check from point p.

Definition at line 1964 of file map.cpp.

1965{
1966 if( p.z > OVERMAP_HEIGHT || p.z < -OVERMAP_DEPTH ) {
1967 debugmsg( "climb_difficulty on out of bounds point: %d, %d, %d", p.x, p.y, p.z );
1968 return INT_MAX;
1969 }
1970
1971 int best_difficulty = INT_MAX;
1972 int blocks_movement = 0;
1973 if( has_flag( "LADDER", p ) ) {
1974 // Really easy, but you have to stand on the tile
1975 return 1;
1976 } else if( has_flag( TFLAG_RAMP, p ) || has_flag( TFLAG_RAMP_UP, p ) ||
1977 has_flag( TFLAG_RAMP_DOWN, p ) ) {
1978 // We're on something stair-like, so halfway there already
1979 best_difficulty = 7;
1980 }
1981
1982 for( const auto &pt : points_in_radius( p, 1 ) ) {
1983 if( impassable_ter_furn( pt ) ) {
1984 // TODO: Non-hardcoded climbability
1985 best_difficulty = std::min( best_difficulty, 10 );
1986 blocks_movement++;
1987 } else if( veh_at( pt ) ) {
1988 // Vehicle tiles are quite good for climbing
1989 // TODO: Penalize spiked parts?
1990 best_difficulty = std::min( best_difficulty, 7 );
1991 }
1992
1993 if( best_difficulty > 5 && has_flag( "CLIMBABLE", pt ) ) {
1994 best_difficulty = 5;
1995 }
1996 }
1997
1998 // TODO: Make this more sensible - check opposite sides, not just movement blocker count
1999 return best_difficulty - blocks_movement;
2000}
bool impassable_ter_furn(const tripoint &p) const
Definition: map.cpp:1823
@ TFLAG_RAMP_UP
Definition: mapdata.h:313
@ TFLAG_RAMP
Definition: mapdata.h:314
@ TFLAG_RAMP_DOWN
Definition: mapdata.h:312

References debugmsg, has_flag(), impassable_ter_furn(), OVERMAP_DEPTH, OVERMAP_HEIGHT, points_in_radius(), TFLAG_RAMP, TFLAG_RAMP_DOWN, TFLAG_RAMP_UP, veh_at(), tripoint::x, tripoint::y, and tripoint::z.

◆ clip_to_bounds() [1/3]

void map::clip_to_bounds ( int &  x,
int &  y 
) const

Definition at line 8680 of file map.cpp.

8681{
8682 if( x < 0 ) {
8683 x = 0;
8684 } else if( x >= SEEX * my_MAPSIZE ) {
8685 x = SEEX * my_MAPSIZE - 1;
8686 }
8687
8688 if( y < 0 ) {
8689 y = 0;
8690 } else if( y >= SEEY * my_MAPSIZE ) {
8691 y = SEEY * my_MAPSIZE - 1;
8692 }
8693}

References my_MAPSIZE, SEEX, and SEEY.

◆ clip_to_bounds() [2/3]

void map::clip_to_bounds ( int &  x,
int &  y,
int &  z 
) const

Definition at line 8695 of file map.cpp.

8696{
8697 clip_to_bounds( x, y );
8698 if( z < -OVERMAP_DEPTH ) {
8699 z = -OVERMAP_DEPTH;
8700 } else if( z > OVERMAP_HEIGHT ) {
8701 z = OVERMAP_HEIGHT;
8702 }
8703}
void clip_to_bounds(tripoint &p) const
Clips the coordinates of p to fit the map bounds.
Definition: map.cpp:8675

References clip_to_bounds(), OVERMAP_DEPTH, and OVERMAP_HEIGHT.

◆ clip_to_bounds() [3/3]

void map::clip_to_bounds ( tripoint p) const

Clips the coordinates of p to fit the map bounds.

Definition at line 8675 of file map.cpp.

8676{
8677 clip_to_bounds( p.x, p.y, p.z );
8678}

References clip_to_bounds(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by MapgenRemovePartHandler::add_item_or_charges(), clip_to_bounds(), and route().

◆ close_door()

bool map::close_door ( const tripoint p,
bool  inside,
bool  check_only 
)

Definition at line 3953 of file map.cpp.

3954{
3955 if( has_flag( "OPENCLOSE_INSIDE", p ) && !inside ) {
3956 return false;
3957 }
3958
3959 const auto &ter = this->ter( p ).obj();
3960 const auto &furn = this->furn( p ).obj();
3961 if( ter.close && !furn.id ) {
3962 if( !check_only ) {
3963 sounds::sound( p, 10, sounds::sound_t::movement, _( "swish" ), true,
3964 "close_door", ter.id.str() );
3965 ter_set( p, ter.close );
3966 }
3967 return true;
3968 } else if( furn.close ) {
3969 if( !check_only ) {
3970 sounds::sound( p, 10, sounds::sound_t::movement, _( "swish" ), true,
3971 "close_door", furn.id.str() );
3972 furn_set( p, furn.close );
3973 }
3974 return true;
3975 }
3976 return false;
3977}
const string_id< T > & id() const
Definition: ammo_effect.cpp:33

References _, furn(), furn_set(), has_flag(), int_id< T >::id(), sounds::movement, int_id< T >::obj(), sounds::sound(), string_id< T >::str(), ter(), and ter_set().

Referenced by can_interact_at(), doors::close_door(), and game::try_get_right_click_action().

◆ collapse_at()

void map::collapse_at ( const tripoint p,
bool  silent,
bool  was_supporting = false,
bool  destroy_pos = true 
)

Causes a collapse at p, such as from destroying a wall.

Definition at line 2893 of file map.cpp.

2895{
2896 const bool supports = was_supporting || has_flag( TFLAG_SUPPORTS_ROOF, p );
2897 const bool wall = was_supporting || has_flag( TFLAG_WALL, p );
2898 // don't bash again if the caller already bashed here
2899 if( destroy_pos ) {
2900 destroy( p, silent );
2901 crush( p );
2902 make_rubble( p );
2903 }
2904 const bool still_supports = has_flag( TFLAG_SUPPORTS_ROOF, p );
2905
2906 // If something supporting the roof collapsed, see what else collapses
2907 if( supports && !still_supports ) {
2908 for( const tripoint &t : points_in_radius( p, 1 ) ) {
2909 // If z-levels are off, tz == t, so we end up skipping a lot of stuff to avoid bugs.
2910 const tripoint &tz = tripoint( t.xy(), t.z + 1 );
2911 // if nothing above us had the chance of collapsing, move on
2912 if( !one_in( collapse_check( tz ) ) ) {
2913 continue;
2914 }
2915 // if a wall collapses, walls without support from below risk collapsing and
2916 //propagate the collapse upwards
2917 if( zlevels && wall && p == t && has_flag( TFLAG_WALL, tz ) ) {
2918 collapse_at( tz, silent );
2919 }
2920 // floors without support from below risk collapsing into open air and can propagate
2921 // the collapse horizontally but not vertically
2922 if( p != t && ( has_flag( TFLAG_SUPPORTS_ROOF, t ) && has_flag( TFLAG_COLLAPSES, t ) ) ) {
2923 collapse_at( t, silent );
2924 }
2925 // this tile used to support a roof, now it doesn't, which means there is only
2926 // open air above us
2927 if( zlevels ) {
2928 ter_set( tz, t_open_air );
2929 furn_set( tz, f_null );
2931 }
2932 }
2933 }
2934 // it would be great to check if collapsing ceilings smashed through the floor, but
2935 // that's not handled for now
2936}
void crush(const tripoint &p)
Definition: map.cpp:3651
int collapse_check(const tripoint &p)
Checks if a square should collapse, returns the X for the one_in(X) collapse chance.
Definition: map.cpp:2844
void make_rubble(const tripoint &p, const furn_id &rubble_type, bool items, const ter_id &floor_type, bool overwrite=false)
Generates rubble at the given location, if overwrite is true it just writes on top of what currently ...
Definition: map.cpp:2493
@ TFLAG_COLLAPSES
Definition: mapdata.h:288
@ TFLAG_WALL
Definition: mapdata.h:300

References collapse_at(), collapse_check(), crush(), destroy(), f_null, furn_set(), has_flag(), make_rubble(), one_in(), points_in_radius(), propagate_suspension_check(), silent, t_open_air, ter_set(), TFLAG_COLLAPSES, TFLAG_SUPPORTS_ROOF, TFLAG_WALL, and zlevels.

Referenced by bash_ter_success(), collapse_at(), and talk_function::loot_building().

◆ collapse_check()

int map::collapse_check ( const tripoint p)

Checks if a square should collapse, returns the X for the one_in(X) collapse chance.

Definition at line 2844 of file map.cpp.

2845{
2846 const bool collapses = has_flag( TFLAG_COLLAPSES, p );
2847 const bool supports_roof = has_flag( TFLAG_SUPPORTS_ROOF, p );
2848
2849 int num_supports = p.z == -OVERMAP_DEPTH ? 0 : -5;
2850 // if there's support below, things are less likely to collapse
2851 if( p.z > -OVERMAP_DEPTH ) {
2852 const tripoint &pbelow = tripoint( p.xy(), p.z - 1 );
2853 for( const tripoint &tbelow : points_in_radius( pbelow, 1 ) ) {
2854 if( has_flag( TFLAG_SUPPORTS_ROOF, pbelow ) ) {
2855 num_supports += 1;
2856 if( has_flag( TFLAG_WALL, pbelow ) ) {
2857 num_supports += 2;
2858 }
2859 if( tbelow == pbelow ) {
2860 num_supports += 2;
2861 }
2862 }
2863 }
2864 }
2865
2866 for( const tripoint &t : points_in_radius( p, 1 ) ) {
2867 if( p == t ) {
2868 continue;
2869 }
2870
2871 if( collapses ) {
2872 if( has_flag( TFLAG_COLLAPSES, t ) ) {
2873 num_supports++;
2874 } else if( has_flag( TFLAG_SUPPORTS_ROOF, t ) ) {
2875 num_supports += 2;
2876 }
2877 } else if( supports_roof ) {
2878 if( has_flag( TFLAG_SUPPORTS_ROOF, t ) ) {
2879 if( has_flag( TFLAG_WALL, t ) ) {
2880 num_supports += 4;
2881 } else if( !has_flag( TFLAG_COLLAPSES, t ) ) {
2882 num_supports += 3;
2883 }
2884 }
2885 }
2886 }
2887
2888 return 1.7 * num_supports;
2889}

References has_flag(), OVERMAP_DEPTH, points_in_radius(), TFLAG_COLLAPSES, TFLAG_SUPPORTS_ROOF, TFLAG_WALL, tripoint::xy(), and tripoint::z.

Referenced by collapse_at().

◆ collapse_invalid_suspension()

void map::collapse_invalid_suspension ( const tripoint point)

Triggers a recursive collapse of suspended tiles based on their support validity.

Definition at line 2947 of file map.cpp.

2948{
2949 if( !is_suspension_valid( point ) ) {
2951 furn_set( point, f_null );
2952
2954 }
2955}
bool is_suspension_valid(const tripoint &point)
Checks the four orientations in which a suspended tile could be valid, and returns if the tile is val...
Definition: map.cpp:2957

References f_null, furn_set(), is_suspension_valid(), propagate_suspension_check(), t_open_air, and ter_set().

Referenced by drop_everything(), and propagate_suspension_check().

◆ combined_movecost()

int map::combined_movecost ( const tripoint from,
const tripoint to,
const vehicle ignored_vehicle = nullptr,
int  modifier = 0,
bool  flying = false,
bool  via_ramp = false 
) const

Cost to move out of one tile and into the next.

Returns
The cost in turns to move out of tripoint from and into to

Definition at line 1833 of file map.cpp.

1836{
1837 const int mults[4] = { 0, 50, 71, 100 };
1838 const int cost1 = move_cost( from, ignored_vehicle );
1839 const int cost2 = move_cost( to, ignored_vehicle );
1840 // Multiply cost depending on the number of differing axes
1841 // 0 if all axes are equal, 100% if only 1 differs, 141% for 2, 200% for 3
1842 size_t match = trigdist ? ( from.x != to.x ) + ( from.y != to.y ) + ( from.z != to.z ) : 1;
1843 if( flying || from.z == to.z ) {
1844 return ( cost1 + cost2 + modifier ) * mults[match] / 2;
1845 }
1846
1847 // Inter-z-level movement by foot (not flying)
1848 if( !valid_move( from, to, false, via_ramp ) ) {
1849 return 0;
1850 }
1851
1852 // TODO: Penalize for using stairs
1853 return ( cost1 + cost2 + modifier ) * mults[match] / 2;
1854}
bool valid_move(const tripoint &from, const tripoint &to, bool bash=false, bool flying=false, bool via_ramp=false) const
Returns true if a creature could walk from from to to in one step.
Definition: map.cpp:1856

References move_cost(), trigdist, valid_move(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by npc::move_away_from(), npc::move_to(), and game::walk_move().

◆ computer_at()

computer * map::computer_at ( const tripoint p)

Definition at line 5520 of file map.cpp.

5521{
5522 if( !inbounds( p ) ) {
5523 return nullptr;
5524 }
5525
5526 point l;
5527 submap *const sm = get_submap_at( p, l );
5528 return sm->get_computer( l );
5529}

References get_submap_at(), inbounds(), and coords::sm.

Referenced by mission_start::reveal_lab_train_depot(), and game::use_computer().

◆ copy_grid()

void map::copy_grid ( const tripoint to,
const tripoint from 
)
protected

Definition at line 7365 of file map.cpp.

7366{
7367 const auto smap = get_submap_at_grid( from );
7368 setsubmap( get_nonant( to ), smap );
7369 for( auto &it : smap->vehicles ) {
7370 it->sm_pos = to;
7371 }
7372}
void setsubmap(size_t grididx, submap *smap)
Set the submap pointer in grid at the give index.
Definition: map.cpp:8103
size_t get_nonant(const tripoint &gridp) const
Get the index of a submap pointer in the grid given by grid coordinates.
Definition: map.cpp:8136

References get_nonant(), get_submap_at_grid(), and setsubmap().

Referenced by shift().

◆ could_see_items() [1/2]

bool map::could_see_items ( const tripoint p,
const Creature who 
) const

Check if the creature could see items at p if there were any items.

This is similar to sees_some_items, but it does not check that there are actually any items.

Definition at line 4726 of file map.cpp.

4727{
4728 return could_see_items( p, who.pos() );
4729}
virtual const tripoint & pos() const =0
bool could_see_items(const tripoint &p, const Creature &who) const
Check if the creature could see items at p if there were any items.
Definition: map.cpp:4726

References could_see_items(), and Creature::pos().

Referenced by could_see_items(), game::print_items_info(), and sees_some_items().

◆ could_see_items() [2/2]

bool map::could_see_items ( const tripoint p,
const tripoint from 
) const

Definition at line 4731 of file map.cpp.

4732{
4733 static const std::string container_string( "CONTAINER" );
4734 const bool container = has_flag_ter_or_furn( container_string, p );
4735 const bool sealed = has_flag_ter_or_furn( TFLAG_SEALED, p );
4736 if( sealed && container ) {
4737 // never see inside of sealed containers
4738 return false;
4739 }
4740 if( container ) {
4741 // can see inside of containers if adjacent or
4742 // on top of the container
4743 return ( std::abs( p.x - from.x ) <= 1 &&
4744 std::abs( p.y - from.y ) <= 1 &&
4745 std::abs( p.z - from.z ) <= 1 );
4746 }
4747 return true;
4748}
bool has_flag_ter_or_furn(const std::string &flag, const tripoint &p) const
Definition: map.cpp:2317
@ TFLAG_SEALED
Definition: mapdata.h:285

References has_flag_ter_or_furn(), TFLAG_SEALED, tripoint::x, tripoint::y, and tripoint::z.

◆ coverage()

int map::coverage ( const tripoint p) const

Returns coverage value of the tile.

Definition at line 6210 of file map.cpp.

6211{
6212 if( const auto obstacle_f = furn( p ) ) {
6213 return obstacle_f->coverage;
6214 }
6215 if( const auto vp = veh_at( p ) ) {
6216 if( vp->obstacle_at_part() ) {
6217 return 60;
6218 } else if( !vp->part_with_feature( VPFLAG_AISLE, true ) ) {
6219 return 45;
6220 }
6221 }
6222 return ter( p )->coverage;
6223}
@ VPFLAG_AISLE
Definition: veh_type.h:40

References map_data_common_t::coverage, furn(), ter(), veh_at(), and VPFLAG_AISLE.

Referenced by build_vision_transparency_cache(), and game::print_terrain_info().

◆ create_anomaly() [1/2]

void map::create_anomaly ( const point cp,
artifact_natural_property  prop,
bool  create_rubble = true 
)
inline

Definition at line 1361 of file map.h.

1361 {
1362 create_anomaly( tripoint( cp, abs_sub.z ), prop, create_rubble );
1363 }
void create_anomaly(const tripoint &p, artifact_natural_property prop, bool create_rubble=true)
Definition: mapgen.cpp:6320

References abs_sub, create_anomaly(), and tripoint::z.

◆ create_anomaly() [2/2]

void map::create_anomaly ( const tripoint p,
artifact_natural_property  prop,
bool  create_rubble = true 
)

Definition at line 6320 of file mapgen.cpp.

6321{
6322 // TODO: Z
6323 point c( cp.xy() );
6324 if( create_rubble ) {
6325 rough_circle( this, t_dirt, c, 11 );
6326 rough_circle_furn( this, f_rubble, c, 5 );
6327 furn_set( c, f_null );
6328 }
6329 switch( prop ) {
6330 case ARTPROP_WRIGGLING:
6331 case ARTPROP_MOVING:
6332 for( int i = c.x - 5; i <= c.x + 5; i++ ) {
6333 for( int j = c.y - 5; j <= c.y + 5; j++ ) {
6334 if( furn( point( i, j ) ) == f_rubble ) {
6335 add_field( {i, j, abs_sub.z}, fd_push_items, 1 );
6336 if( one_in( 3 ) ) {
6337 spawn_item( point( i, j ), "rock" );
6338 }
6339 }
6340 }
6341 }
6342 break;
6343
6344 case ARTPROP_GLOWING:
6345 case ARTPROP_GLITTERING:
6346 for( int i = c.x - 5; i <= c.x + 5; i++ ) {
6347 for( int j = c.y - 5; j <= c.y + 5; j++ ) {
6348 if( furn( point( i, j ) ) == f_rubble && one_in( 2 ) ) {
6349 mtrap_set( this, point( i, j ), tr_glow );
6350 }
6351 }
6352 }
6353 break;
6354
6355 case ARTPROP_HUMMING:
6356 case ARTPROP_RATTLING:
6357 for( int i = c.x - 5; i <= c.x + 5; i++ ) {
6358 for( int j = c.y - 5; j <= c.y + 5; j++ ) {
6359 if( furn( point( i, j ) ) == f_rubble && one_in( 2 ) ) {
6360 mtrap_set( this, point( i, j ), tr_hum );
6361 }
6362 }
6363 }
6364 break;
6365
6366 case ARTPROP_WHISPERING:
6367 case ARTPROP_ENGRAVED:
6368 for( int i = c.x - 5; i <= c.x + 5; i++ ) {
6369 for( int j = c.y - 5; j <= c.y + 5; j++ ) {
6370 if( furn( point( i, j ) ) == f_rubble && one_in( 3 ) ) {
6371 mtrap_set( this, point( i, j ), tr_shadow );
6372 }
6373 }
6374 }
6375 break;
6376
6377 case ARTPROP_BREATHING:
6378 for( int i = c.x - 1; i <= c.x + 1; i++ ) {
6379 for( int j = c.y - 1; j <= c.y + 1; j++ ) {
6380 if( i == c.x && j == c.y ) {
6381 place_spawns( GROUP_BREATHER_HUB, 1, point( i, j ), point( i, j ), 1,
6382 true );
6383 } else {
6384 place_spawns( GROUP_BREATHER, 1, point( i, j ), point( i, j ), 1, true );
6385 }
6386 }
6387 }
6388 break;
6389
6390 case ARTPROP_DEAD:
6391 for( int i = c.x - 5; i <= c.x + 5; i++ ) {
6392 for( int j = c.y - 5; j <= c.y + 5; j++ ) {
6393 if( furn( point( i, j ) ) == f_rubble ) {
6394 mtrap_set( this, point( i, j ), tr_drain );
6395 }
6396 }
6397 }
6398 break;
6399
6400 case ARTPROP_ITCHY:
6401 for( int i = c.x - 5; i <= c.x + 5; i++ ) {
6402 for( int j = c.y - 5; j <= c.y + 5; j++ ) {
6403 if( furn( point( i, j ) ) == f_rubble ) {
6404 set_radiation( point( i, j ), rng( 0, 10 ) );
6405 }
6406 }
6407 }
6408 break;
6409
6410 case ARTPROP_ELECTRIC:
6411 case ARTPROP_CRACKLING:
6412 add_field( {c, abs_sub.z}, fd_shock_vent, 3 );
6413 break;
6414
6415 case ARTPROP_SLIMY:
6416 add_field( {c, abs_sub.z}, fd_acid_vent, 3 );
6417 break;
6418
6419 case ARTPROP_WARM:
6420 for( int i = c.x - 5; i <= c.x + 5; i++ ) {
6421 for( int j = c.y - 5; j <= c.y + 5; j++ ) {
6422 if( furn( point( i, j ) ) == f_rubble ) {
6423 add_field( {i, j, abs_sub.z}, fd_fire_vent, 1 + ( rl_dist( c, point( i, j ) ) % 3 ) );
6424 }
6425 }
6426 }
6427 break;
6428
6429 case ARTPROP_SCALED:
6430 for( int i = c.x - 5; i <= c.x + 5; i++ ) {
6431 for( int j = c.y - 5; j <= c.y + 5; j++ ) {
6432 if( furn( point( i, j ) ) == f_rubble ) {
6433 mtrap_set( this, point( i, j ), tr_snake );
6434 }
6435 }
6436 }
6437 break;
6438
6439 case ARTPROP_FRACTAL:
6440 create_anomaly( c + point( -4, -4 ),
6441 static_cast<artifact_natural_property>( rng( ARTPROP_NULL + 1, ARTPROP_MAX - 1 ) ) );
6442 create_anomaly( c + point( 4, -4 ),
6443 static_cast<artifact_natural_property>( rng( ARTPROP_NULL + 1, ARTPROP_MAX - 1 ) ) );
6444 create_anomaly( c + point( -4, 4 ),
6445 static_cast<artifact_natural_property>( rng( ARTPROP_NULL + 1, ARTPROP_MAX - 1 ) ) );
6446 create_anomaly( c + point( 4, -4 ),
6447 static_cast<artifact_natural_property>( rng( ARTPROP_NULL + 1, ARTPROP_MAX - 1 ) ) );
6448 break;
6449 default:
6450 break;
6451 }
6452}
bool add_field(const tripoint &p, const field_type_id &type_id, int intensity=INT_MAX, const time_duration &age=0_turns, bool hit_player=true)
Add field entry at point, or set intensity if present.
Definition: map.cpp:5386
void place_spawns(const mongroup_id &group, int chance, const point &p1, const point &p2, float density, bool individual=false, bool friendly=false, const std::string &name="NONE", int mission_id=-1)
Definition: mapgen.cpp:5389
void set_radiation(const tripoint &p, int value)
Definition: map.cpp:4025
void spawn_item(const tripoint &p, const itype_id &type_id, unsigned quantity=1, int charges=0, const time_point &birthday=calendar::start_of_cataclysm, int damlevel=0)
Definition: map.cpp:4173
artifact_natural_property
Definition: enums.h:152
@ ARTPROP_GLITTERING
Definition: enums.h:162
@ ARTPROP_ITCHY
Definition: enums.h:161
@ ARTPROP_RATTLING
Definition: enums.h:168
@ ARTPROP_WRIGGLING
Definition: enums.h:154
@ ARTPROP_HUMMING
Definition: enums.h:156
@ ARTPROP_WHISPERING
Definition: enums.h:158
@ ARTPROP_ENGRAVED
Definition: enums.h:165
@ ARTPROP_ELECTRIC
Definition: enums.h:163
@ ARTPROP_FRACTAL
Definition: enums.h:170
@ ARTPROP_SCALED
Definition: enums.h:169
@ ARTPROP_GLOWING
Definition: enums.h:155
@ ARTPROP_NULL
Definition: enums.h:153
@ ARTPROP_DEAD
Definition: enums.h:160
@ ARTPROP_BREATHING
Definition: enums.h:159
@ ARTPROP_MAX
Definition: enums.h:171
@ ARTPROP_CRACKLING
Definition: enums.h:166
@ ARTPROP_WARM
Definition: enums.h:167
@ ARTPROP_MOVING
Definition: enums.h:157
@ ARTPROP_SLIMY
Definition: enums.h:164
field_type_id fd_fire_vent
Definition: field_type.cpp:351
field_type_id fd_acid_vent
Definition: field_type.cpp:357
field_type_id fd_push_items
Definition: field_type.cpp:355
field_type_id fd_shock_vent
Definition: field_type.cpp:356
furn_id f_rubble
Definition: mapdata.cpp:1097
void rough_circle(map *m, const ter_id &type, const point &p, int rad)
Definition: mapgen.cpp:6487
void rough_circle_furn(map *m, const furn_id &type, const point &p, int rad)
Definition: mapgen.cpp:6491
static const mongroup_id GROUP_BREATHER("GROUP_BREATHER")
static const mongroup_id GROUP_BREATHER_HUB("GROUP_BREATHER_HUB")
void mtrap_set(map *m, const point &p, trap_id type)
static const trap_str_id tr_drain("tr_drain")
static const trap_str_id tr_snake("tr_snake")
static const trap_str_id tr_shadow("tr_shadow")
trap_id tr_glow
Definition: trap.cpp:312
trap_id tr_hum
Definition: trap.cpp:313

References abs_sub, add_field(), ARTPROP_BREATHING, ARTPROP_CRACKLING, ARTPROP_DEAD, ARTPROP_ELECTRIC, ARTPROP_ENGRAVED, ARTPROP_FRACTAL, ARTPROP_GLITTERING, ARTPROP_GLOWING, ARTPROP_HUMMING, ARTPROP_ITCHY, ARTPROP_MAX, ARTPROP_MOVING, ARTPROP_NULL, ARTPROP_RATTLING, ARTPROP_SCALED, ARTPROP_SLIMY, ARTPROP_WARM, ARTPROP_WHISPERING, ARTPROP_WRIGGLING, c, create_anomaly(), f_null, f_rubble, fd_acid_vent, fd_fire_vent, fd_push_items, fd_shock_vent, furn(), furn_set(), GROUP_BREATHER, GROUP_BREATHER_HUB, mtrap_set(), one_in(), place_spawns(), rl_dist(), rng(), rough_circle(), rough_circle_furn(), set_radiation(), spawn_item(), t_dirt, tr_drain, tr_glow, tr_hum, tr_shadow, tr_snake, tripoint::xy(), and tripoint::z.

Referenced by create_anomaly(), debug_menu::debug(), draw_lab(), and MapExtras::mx_portal_in().

◆ create_burnproducts()

void map::create_burnproducts ( const tripoint p,
const item fuel,
const units::mass burned_mass 
)

Definition at line 96 of file map_field.cpp.

97{
98 std::vector<material_id> all_mats = fuel.made_of();
99 if( all_mats.empty() ) {
100 return;
101 }
102 // Items that are multiple materials are assumed to be equal parts each.
103 const units::mass by_weight = burned_mass / all_mats.size();
104 for( material_id &mat : all_mats ) {
105 for( auto &bp : mat->burn_products() ) {
106 itype_id id = bp.first;
107 // Spawning the same item as the one that was just burned is pointless
108 // and leads to infinite recursion.
109 if( fuel.typeId() == id ) {
110 continue;
111 }
112 const float eff = bp.second;
113 const int n = std::floor( eff * ( by_weight / id->weight ) );
114
115 if( n <= 0 ) {
116 continue;
117 }
118 spawn_item( p, id, n, 1, calendar::turn );
119 }
120 }
121}
const std::string id
Definition: basecamp.h:87

References base_camps::id, item::made_of(), spawn_item(), calendar::turn, and item::typeId().

Referenced by MapExtras::burned_ground_parser(), and process_fields_in_submap().

◆ create_hot_air()

void map::create_hot_air ( const tripoint p,
int  intensity 
)
private

Definition at line 361 of file map_field.cpp.

362{
363 field_type_id hot_air;
364 switch( intensity ) {
365 case 1:
366 hot_air = fd_hot_air1;
367 break;
368 case 2:
369 hot_air = fd_hot_air2;
370 break;
371 case 3:
372 hot_air = fd_hot_air3;
373 break;
374 case 4:
375 hot_air = fd_hot_air4;
376 break;
377 default:
378 debugmsg( "Tried to spread hot air with intensity %d", intensity );
379 return;
380 }
381
382 for( int counter = 0; counter < 5; counter++ ) {
383 tripoint dst( p + point( rng( -1, 1 ), rng( -1, 1 ) ) );
384 add_field( dst, hot_air, 1 );
385 }
386}
field_type_id fd_hot_air3
Definition: field_type.cpp:381
field_type_id fd_hot_air2
Definition: field_type.cpp:380
field_type_id fd_hot_air1
Definition: field_type.cpp:379
field_type_id fd_hot_air4
Definition: field_type.cpp:382

References add_field(), debugmsg, fd_hot_air1, fd_hot_air2, fd_hot_air3, fd_hot_air4, and rng().

Referenced by process_fields_in_submap().

◆ creature_in_field()

void map::creature_in_field ( Creature critter)

Apply field effects to the creature when it's on a square with fields.

Definition at line 1560 of file map_field.cpp.

1561{
1562 bool in_vehicle = false;
1563 bool inside_vehicle = false;
1564 player *u = critter.as_player();
1565 if( critter.is_monster() ) {
1566 monster_in_field( *static_cast<monster *>( &critter ) );
1567 } else {
1568 if( u ) {
1569 in_vehicle = u->in_vehicle;
1570 // If we are in a vehicle figure out if we are inside (reduces effects usually)
1571 // and what part of the vehicle we need to deal with.
1572 if( in_vehicle ) {
1573 if( const optional_vpart_position vp = veh_at( u->pos() ) ) {
1574 if( vp->is_inside() ) {
1575 inside_vehicle = true;
1576 }
1577 }
1578 }
1579 player_in_field( *u );
1580 }
1581 }
1582
1583 field &curfield = get_field( critter.pos() );
1584 for( auto &field_entry_it : curfield ) {
1585 field_entry &cur_field_entry = field_entry_it.second;
1586 if( !cur_field_entry.is_field_alive() ) {
1587 continue;
1588 }
1589 const field_type_id cur_field_id = cur_field_entry.get_field_type();
1590
1591 for( const auto &fe : cur_field_entry.field_effects() ) {
1592 if( in_vehicle && fe.immune_in_vehicle ) {
1593 continue;
1594 }
1595 if( inside_vehicle && fe.immune_inside_vehicle ) {
1596 continue;
1597 }
1598 if( !inside_vehicle && fe.immune_outside_vehicle ) {
1599 continue;
1600 }
1601 if( in_vehicle && !one_in( fe.chance_in_vehicle ) ) {
1602 continue;
1603 }
1604 if( inside_vehicle && !one_in( fe.chance_inside_vehicle ) ) {
1605 continue;
1606 }
1607 if( !inside_vehicle && !one_in( fe.chance_outside_vehicle ) ) {
1608 continue;
1609 }
1610
1611 const effect field_fx = fe.get_effect();
1612 if( critter.is_immune_field( cur_field_id ) || critter.is_immune_effect( field_fx.get_id() ) ) {
1613 continue;
1614 }
1615 bool effect_added = false;
1616 if( fe.is_environmental ) {
1617 effect_added = critter.add_env_effect( fe.id, fe.bp->token, fe.intensity, fe.get_duration() );
1618 } else {
1619 effect_added = true;
1620 critter.add_effect( field_fx );
1621 }
1622 if( effect_added ) {
1623 critter.add_msg_player_or_npc( fe.env_message_type, fe.get_message(), fe.get_message_npc() );
1624 }
1625 }
1626 }
1627}
bool in_vehicle
Definition: character.h:1577
virtual bool is_monster() const
Definition: creature.h:101
virtual bool is_immune_field(const field_type_id &) const
Returns true if we are immune to the field type with the given fid.
Definition: creature.h:325
virtual void add_msg_player_or_npc(const std::string &, const std::string &) const
Definition: creature.h:677
virtual player * as_player()
Definition: creature.h:122
virtual bool is_immune_effect(const efftype_id &type) const =0
Definition: effect.h:161
const efftype_id & get_id() const
Returns the effect's matching effect_type id.
Definition: effect.h:305
std::vector< field_effect > field_effects() const
Definition: field.cpp:294
bool is_field_alive()
Definition: field.h:89
field_type_id get_field_type() const
Definition: field.cpp:105
A variable sized collection of field entries on a given map square.
Definition: field.h:131
void player_in_field(player &u)
Definition: map_field.cpp:1221
void monster_in_field(monster &z)
Definition: map_field.cpp:1629

References Creature::add_effect(), Creature::add_env_effect(), Creature::add_msg_player_or_npc(), Creature::as_player(), field_entry::field_effects(), get_field(), field_entry::get_field_type(), effect::get_id(), Character::in_vehicle, field_entry::is_field_alive(), Creature::is_immune_effect(), Creature::is_immune_field(), Creature::is_monster(), monster_in_field(), one_in(), player_in_field(), Creature::pos(), Character::pos(), and veh_at().

Referenced by add_field(), game::do_turn(), game::monmove(), npc::move_to(), and game::place_player().

◆ creature_on_trap()

void map::creature_on_trap ( Creature critter,
bool  may_avoid = true 
)

Apply trap effects to the creature, similar to creature_in_field.

If there is no trap at the creatures location, nothing is done. If the creature can avoid the trap, nothing is done as well. Otherwise the trap is triggered.

Parameters
critterCreature that just got trapped
may_avoidIf true, the creature tries to avoid the trap (Creature::avoid_trap). If false, the trap is always triggered.

Definition at line 8285 of file map.cpp.

8286{
8287 const auto &tr = tr_at( c.pos() );
8288 if( tr.is_null() ) {
8289 return;
8290 }
8291 // boarded in a vehicle means the player is above the trap, like a flying monster and can
8292 // never trigger the trap.
8293 const player *const p = dynamic_cast<const player *>( &c );
8294 if( p != nullptr && p->in_vehicle ) {
8295 return;
8296 }
8297 if( may_avoid && c.avoid_trap( c.pos(), tr ) ) {
8298 return;
8299 }
8300 tr.trigger( c.pos(), &c );
8301}

References c, Character::in_vehicle, and tr_at().

Referenced by game::fling_creature(), iexamine::ledge(), npc::move_to(), game::phasing_move(), game::place_player(), smash(), and game::vertical_move().

◆ crush()

void map::crush ( const tripoint p)

Definition at line 3651 of file map.cpp.

3652{
3653 player *crushed_player = g->critter_at<player>( p );
3654
3655 if( crushed_player != nullptr ) {
3656 bool player_inside = false;
3657 if( crushed_player->in_vehicle ) {
3658 const optional_vpart_position vp = veh_at( p );
3659 player_inside = vp && vp->is_inside();
3660 }
3661 if( !player_inside ) { //If there's a player at p and he's not in a covered vehicle...
3662 //This is the roof coming down on top of us, no chance to dodge
3663 crushed_player->add_msg_player_or_npc( m_bad, _( "You are crushed by the falling debris!" ),
3664 _( "<npcname> is crushed by the falling debris!" ) );
3665 // TODO: Make this depend on the ceiling material
3666 const int dam = rng( 0, 40 );
3667 // Torso and head take the brunt of the blow
3668 crushed_player->deal_damage( nullptr, bodypart_id( "head" ), damage_instance( DT_BASH,
3669 dam * .25 ) );
3670 crushed_player->deal_damage( nullptr, bodypart_id( "torso" ), damage_instance( DT_BASH,
3671 dam * .45 ) );
3672 // Legs take the next most through transferred force
3673 crushed_player->deal_damage( nullptr, bodypart_id( "leg_l" ), damage_instance( DT_BASH,
3674 dam * .10 ) );
3675 crushed_player->deal_damage( nullptr, bodypart_id( "leg_r" ), damage_instance( DT_BASH,
3676 dam * .10 ) );
3677 // Arms take the least
3678 crushed_player->deal_damage( nullptr, bodypart_id( "arm_l" ), damage_instance( DT_BASH,
3679 dam * .05 ) );
3680 crushed_player->deal_damage( nullptr, bodypart_id( "arm_r" ), damage_instance( DT_BASH,
3681 dam * .05 ) );
3682
3683 // Pin whoever got hit
3684 crushed_player->add_effect( effect_crushed, 1_turns, num_bp );
3685 crushed_player->check_dead_state();
3686 }
3687 }
3688
3689 if( monster *const monhit = g->critter_at<monster>( p ) ) {
3690 // 25 ~= 60 * .45 (torso)
3691 monhit->deal_damage( nullptr, bodypart_id( "torso" ), damage_instance( DT_BASH, rng( 0, 25 ) ) );
3692
3693 // Pin whoever got hit
3694 monhit->add_effect( effect_crushed, 1_turns, num_bp );
3695 monhit->check_dead_state();
3696 }
3697
3698 if( const optional_vpart_position vp = veh_at( p ) ) {
3699 // Arbitrary number is better than collapsing house roof crushing APCs
3700 vp->vehicle().damage( vp->part_index(), rng( 100, 1000 ), DT_BASH, false );
3701 }
3702}
int_id< body_part_type > bodypart_id
Definition: bodypart.h:23
@ num_bp
Definition: bodypart.h:52
void check_dead_state()
This function checks the creatures is_dead_state and (if true) calls die.
Definition: creature.cpp:1836
void add_msg_player_or_npc(const std::string &player_msg, const std::string &npc_str) const override
Definition: player.cpp:4373
@ m_bad
Definition: enums.h:254
static const efftype_id effect_crushed("crushed")

References _, Creature::add_effect(), player::add_msg_player_or_npc(), Creature::check_dead_state(), Character::deal_damage(), DT_BASH, effect_crushed, g, Character::in_vehicle, m_bad, num_bp, rng(), and veh_at().

Referenced by collapse_at().

◆ dangerous_field_at()

bool map::dangerous_field_at ( const tripoint p)

Definition at line 5375 of file map.cpp.

5376{
5377 for( auto &pr : field_at( p ) ) {
5378 auto &fd = pr.second;
5379 if( fd.is_dangerous() ) {
5380 return true;
5381 }
5382 }
5383 return false;
5384}
const field & field_at(const tripoint &p) const
Get the fields that are here.
Definition: map.cpp:5277

References field_at().

Referenced by are_requirements_nearby(), and generic_multi_activity_locations().

◆ decay_cosmetic_fields()

void map::decay_cosmetic_fields ( const tripoint p,
const time_duration time_since_last_actualize 
)
protected

Definition at line 7244 of file map.cpp.

7246{
7247 for( auto &pr : field_at( p ) ) {
7248 auto &fd = pr.second;
7249 const time_duration hl = fd.get_field_type().obj().half_life;
7250 if( !fd.decays_on_actualize() || hl <= 0_turns ) {
7251 continue;
7252 }
7253
7254 const time_duration added_age = 2 * time_since_last_actualize / rng( 2, 4 );
7255 fd.mod_field_age( added_age );
7256 const int intensity_drop = fd.get_field_age() / hl;
7257 if( intensity_drop > 0 ) {
7258 fd.set_field_intensity( fd.get_field_intensity() - intensity_drop );
7259 fd.mod_field_age( -hl * intensity_drop );
7260 }
7261 }
7262}

References field_at(), and rng().

Referenced by actualize().

◆ decay_fields_and_scent()

void map::decay_fields_and_scent ( const time_duration amount)

Moved here from weather.cpp for speed.

Decays fire, washable fields and scent. Washable fields are decayed only by 1/3 of the amount fire is.

Definition at line 2658 of file map.cpp.

2659{
2660 // TODO: Make this happen on all z-levels
2661
2662 // Decay scent separately, so that later we can use field count to skip empty submaps
2663 g->scent.decay();
2664
2665 // Coordinate code copied from lightmap calculations
2666 // TODO: Z
2667 const int smz = abs_sub.z;
2668 const auto &outside_cache = get_cache_ref( smz ).outside_cache;
2669 for( int smx = 0; smx < my_MAPSIZE; ++smx ) {
2670 for( int smy = 0; smy < my_MAPSIZE; ++smy ) {
2671 const auto cur_submap = get_submap_at_grid( { smx, smy, smz } );
2672 int to_proc = cur_submap->field_count;
2673 if( to_proc < 1 ) {
2674 if( to_proc < 0 ) {
2675 cur_submap->field_count = 0;
2676 dbg( DL::Error ) << "map::decay_fields_and_scent: submap at "
2677 << ( abs_sub + tripoint( smx, smy, 0 ) )
2678 << "has " << to_proc << " field_count";
2679 }
2680 get_cache( smz ).field_cache.reset( smx + ( smy * MAPSIZE ) );
2681 // This submap has no fields
2682 continue;
2683 }
2684
2685 for( int sx = 0; sx < SEEX; ++sx ) {
2686 if( to_proc < 1 ) {
2687 // This submap had some fields, but all got proc'd already
2688 break;
2689 }
2690
2691 for( int sy = 0; sy < SEEY; ++sy ) {
2692 const int x = sx + smx * SEEX;
2693 const int y = sy + smy * SEEY;
2694
2695 field &fields = cur_submap->get_field( { sx, sy} );
2696 if( !outside_cache[x][y] ) {
2697 to_proc -= fields.field_count();
2698 continue;
2699 }
2700
2701 for( auto &fp : fields ) {
2702 to_proc--;
2703 field_entry &cur = fp.second;
2704 const field_type_id type = cur.get_field_type();
2705 const int decay_amount_factor = type.obj().decay_amount_factor;
2706 if( decay_amount_factor != 0 ) {
2707 const time_duration decay_amount = amount / decay_amount_factor;
2708 cur.set_field_age( cur.get_field_age() + decay_amount );
2709 }
2710 }
2711 }
2712 }
2713
2714 if( to_proc > 0 ) {
2715 cur_submap->field_count = cur_submap->field_count - to_proc;
2716 dbg( DL::Error ) << "map::decay_fields_and_scent: submap at "
2717 << abs_sub + tripoint( smx, smy, 0 )
2718 << "has " << cur_submap->field_count - to_proc << "fields, but "
2719 << cur_submap->field_count << " field_count";
2720 }
2721 }
2722 }
2723}
time_duration set_field_age(const time_duration &new_age)
Sets age to the given value.
Definition: field.cpp:138
time_duration get_field_age() const
Definition: field.cpp:133
@ Error
Error (default: enabled).

References abs_sub, dbg, Error, level_cache::field_cache, submap::field_count, g, get_cache(), get_cache_ref(), field_entry::get_field_age(), field_entry::get_field_type(), get_submap_at_grid(), MAPSIZE, my_MAPSIZE, level_cache::outside_cache, SEEX, SEEY, field_entry::set_field_age(), sx, sy, type, and tripoint::z.

◆ delete_graffiti()

void map::delete_graffiti ( const tripoint p)

Definition at line 7670 of file map.cpp.

7671{
7672 if( !inbounds( p ) ) {
7673 return;
7674 }
7675 point l;
7676 submap *const current_submap = get_submap_at( p, l );
7677 current_submap->delete_graffiti( l );
7678}
void delete_graffiti(const point &p)
Definition: submap.cpp:109

References submap::delete_graffiti(), get_submap_at(), and inbounds().

◆ delete_signage()

void map::delete_signage ( const tripoint p) const

Definition at line 4001 of file map.cpp.

4002{
4003 if( !inbounds( p ) ) {
4004 return;
4005 }
4006
4007 point l;
4008 submap *const current_submap = get_submap_at( p, l );
4009
4010 current_submap->delete_signage( l );
4011}
void delete_signage(const point &p)
Definition: submap.cpp:148

References submap::delete_signage(), get_submap_at(), and inbounds().

Referenced by bash_furn_success(), construct::done_deconstruct(), and talk_function::loot_building().

◆ deregister_vehicle_zone()

bool map::deregister_vehicle_zone ( zone_data zone)

Definition at line 958 of file map.cpp.

959{
961 zone.get_start_point() ) ).part_with_feature( "CARGO", false ) ) {
962 auto bounds = vp->vehicle().loot_zones.equal_range( vp->mount() );
963 for( auto it = bounds.first; it != bounds.second; it++ ) {
964 if( &zone == &( it->second ) ) {
965 vp->vehicle().loot_zones.erase( it );
966 return true;
967 }
968 }
969 }
970 return false;
971}
tripoint getlocal(const tripoint &p) const
Inverse of getabs.
Definition: map.cpp:8079
tripoint get_start_point() const
Definition: clzones.h:317

References zone_data::get_start_point(), getlocal(), optional_vpart_position::part_with_feature(), and veh_at().

◆ destroy()

void map::destroy ( const tripoint p,
bool  silent = false 
)

Keeps bashing a square until it can't be bashed anymore.

Definition at line 3617 of file map.cpp.

3618{
3619 // Break if it takes more than 25 destructions to remove to prevent infinite loops
3620 // Example: A bashes to B, B bashes to A leads to A->B->A->...
3621
3622 // If we were destroying a floor, allow destroying floors
3623 // If we were destroying something unpassable, destroy only that
3624 bool was_impassable = impassable( p );
3625 int count = 0;
3626 while( count <= 25
3627 && bash( p, 999, silent, true ).success
3628 && ( !was_impassable || impassable( p ) ) ) {
3629 count++;
3630 }
3631}

References bash(), detail::count(), impassable(), silent, and behavior::success.

Referenced by add_vehicle_to_map(), bash(), MapExtras::burned_ground_parser(), activity_handlers::burrow_finish(), collapse_at(), draw_lab(), activity_handlers::jackhammer_finish(), make_rubble(), MapExtras::mx_crater(), MapExtras::mx_helicopter(), MapExtras::mx_supplydrop(), om_cutdown_trees(), activity_handlers::pickaxe_finish(), process_fields_in_submap(), and explosion_handler::explosion_funcs::resonance_cascade().

◆ destroy_furn()

void map::destroy_furn ( const tripoint p,
bool  silent = false 
)

Keeps bashing a square until there is no more furniture.

Definition at line 3633 of file map.cpp.

3634{
3635 // Break if it takes more than 25 destructions to remove to prevent infinite loops
3636 // Example: A bashes to B, B bashes to A leads to A->B->A->...
3637 int count = 0;
3638 while( count <= 25 && furn( p ) != f_null && bash( p, 999, silent, true ).success ) {
3639 count++;
3640 }
3641}

References bash(), detail::count(), f_null, furn(), silent, and behavior::success.

Referenced by construct::done_grave(), and make_rubble().

◆ destroy_vehicle()

◆ detach_vehicle()

std::unique_ptr< vehicle > map::detach_vehicle ( vehicle veh)

Definition at line 350 of file map.cpp.

351{
352 if( veh == nullptr ) {
353 debugmsg( "map::detach_vehicle was passed nullptr" );
354 return std::unique_ptr<vehicle>();
355 }
356
357 int z = veh->sm_pos.z;
358 if( z < -OVERMAP_DEPTH || z > OVERMAP_HEIGHT ) {
359 debugmsg( "detach_vehicle got a vehicle outside allowed z-level range! name=%s, submap:%d,%d,%d",
360 veh->name, veh->sm_pos.x, veh->sm_pos.y, veh->sm_pos.z );
361 // Try to fix by moving the vehicle here
362 z = veh->sm_pos.z = abs_sub.z;
363 }
364
365 // Unboard all passengers before detaching
366 for( auto const &part : veh->get_avail_parts( VPFLAG_BOARDABLE ) ) {
367 player *passenger = part.get_passenger();
368 if( passenger ) {
369 unboard_vehicle( part, passenger );
370 }
371 }
372 veh->invalidate_towing( true );
373 submap *const current_submap = get_submap_at_grid( veh->sm_pos );
374 level_cache &ch = get_cache( z );
375 for( size_t i = 0; i < current_submap->vehicles.size(); i++ ) {
376 if( current_submap->vehicles[i].get() == veh ) {
377 ch.vehicle_list.erase( veh );
378 ch.zone_vehicles.erase( veh );
380 std::unique_ptr<vehicle> result = std::move( current_submap->vehicles[i] );
381 current_submap->vehicles.erase( current_submap->vehicles.begin() + i );
382 if( veh->tracking_on ) {
384 }
385 dirty_vehicle_list.erase( veh );
386 veh->detach();
387 veh->refresh_position();
388 return result;
389 }
390 }
391 debugmsg( "detach_vehicle can't find it! name=%s, submap:%d,%d,%d", veh->name, veh->sm_pos.x,
392 veh->sm_pos.y, veh->sm_pos.z );
393 return std::unique_ptr<vehicle>();
394}
std::set< vehicle * > dirty_vehicle_list
Definition: map.h:1618
void reset_vehicle_cache()
Definition: map.cpp:250
void remove_vehicle(const vehicle *veh)
Remove the vehicle from being tracked in the overmap.
std::string name
Definition: vehicle.h:1829
void refresh_position()
Definition: vehicle.cpp:5638
bool tracking_on
Definition: vehicle.h:1971
void invalidate_towing(bool first_vehicle=false)
Definition: vehicle.cpp:5952
void detach()
Definition: vehicle.h:768
std::set< vehicle * > zone_vehicles
Definition: map.h:346
std::set< vehicle * > vehicle_list
Definition: map.h:345

References abs_sub, debugmsg, vehicle::detach(), dirty_vehicle_list, vehicle::get_avail_parts(), get_cache(), get_submap_at_grid(), vehicle::invalidate_towing(), avatar_action::move(), vehicle::name, overmap_buffer, OVERMAP_HEIGHT, vehicle::refresh_position(), overmapbuffer::remove_vehicle(), reset_vehicle_cache(), vehicle::sm_pos, vehicle::tracking_on, unboard_vehicle(), level_cache::vehicle_list, submap::vehicles, VPFLAG_BOARDABLE, tripoint::x, tripoint::y, tripoint::z, and level_cache::zone_vehicles.

Referenced by add_vehicle_to_map(), destroy_vehicle(), and editmap::mapgen_veh_destroy().

◆ determine_wall_corner()

int map::determine_wall_corner ( const tripoint p) const
private

Definition at line 7701 of file map.cpp.

7702{
7703 int test_connect_group = ter( p ).obj().connect_group;
7704 uint8_t connections = get_known_connections( p, test_connect_group );
7705 // The bits in connections are SEWN, whereas the characters in LINE_
7706 // constants are NESW, so we want values in 8 | 2 | 1 | 4 order.
7707 switch( connections ) {
7708 case 8 | 2 | 1 | 4:
7709 return LINE_XXXX;
7710 case 0 | 2 | 1 | 4:
7711 return LINE_OXXX;
7712
7713 case 8 | 0 | 1 | 4:
7714 return LINE_XOXX;
7715 case 0 | 0 | 1 | 4:
7716 return LINE_OOXX;
7717
7718 case 8 | 2 | 0 | 4:
7719 return LINE_XXOX;
7720 case 0 | 2 | 0 | 4:
7721 return LINE_OXOX;
7722 case 8 | 0 | 0 | 4:
7723 return LINE_XOOX;
7724 case 0 | 0 | 0 | 4:
7725 return LINE_OXOX; // LINE_OOOX would be better
7726
7727 case 8 | 2 | 1 | 0:
7728 return LINE_XXXO;
7729 case 0 | 2 | 1 | 0:
7730 return LINE_OXXO;
7731 case 8 | 0 | 1 | 0:
7732 return LINE_XOXO;
7733 case 0 | 0 | 1 | 0:
7734 return LINE_XOXO; // LINE_OOXO would be better
7735 case 8 | 2 | 0 | 0:
7736 return LINE_XXOO;
7737 case 0 | 2 | 0 | 0:
7738 return LINE_OXOX; // LINE_OXOO would be better
7739 case 8 | 0 | 0 | 0:
7740 return LINE_XOXO; // LINE_XOOO would be better
7741
7742 case 0 | 0 | 0 | 0:
7743 return ter( p ).obj().symbol(); // technically just a column
7744
7745 default:
7746 // assert( false );
7747 // this shall not happen
7748 return '?';
7749 }
7750}
uint8_t get_known_connections(const tripoint &p, int connect_group, const std::map< tripoint, ter_id > &override={}) const
Definition: map.cpp:1505
generic_factory< overmap_connection > connections("overmap connection")
#define LINE_XOXX
Definition: output.h:47
#define LINE_XOXO
Definition: output.h:39
#define LINE_OXOX
Definition: output.h:40
#define LINE_OOXX
Definition: output.h:43
#define LINE_OXXX
Definition: output.h:48
#define LINE_XXXO
Definition: output.h:45
#define LINE_XXOX
Definition: output.h:46
#define LINE_OXXO
Definition: output.h:42
#define LINE_XOOX
Definition: output.h:44
#define LINE_XXOO
Definition: output.h:41
#define LINE_XXXX
Definition: output.h:49
int symbol() const
Definition: mapdata.cpp:550

References map_data_common_t::connect_group, anonymous_namespace{overmap_connection.cpp}::connections, get_known_connections(), LINE_OOXX, LINE_OXOX, LINE_OXXO, LINE_OXXX, LINE_XOOX, LINE_XOXO, LINE_XOXX, LINE_XXOO, LINE_XXOX, LINE_XXXO, LINE_XXXX, int_id< T >::obj(), map_data_common_t::symbol(), and ter().

Referenced by draw_from_above(), and draw_maptile().

◆ disarm_trap()

void map::disarm_trap ( const tripoint p)
Perception increases chance of disarming trap Dexterity increases chance of disarming trap Traps increases chance of disarming trap

Definition at line 5193 of file map.cpp.

5194{
5195 const trap &tr = tr_at( p );
5196 if( tr.is_null() ) {
5197 debugmsg( "Tried to disarm a trap where there was none (%d %d %d)", p.x, p.y, p.z );
5198 return;
5199 }
5200
5201 const int tSkillLevel = g->u.get_skill_level( skill_traps );
5202 const int diff = tr.get_difficulty();
5203 int roll = rng( tSkillLevel, 4 * tSkillLevel );
5204
5205 // Some traps are not actual traps. Skip the rolls, different message and give the option to grab it right away.
5206 if( tr.get_avoidance() == 0 && tr.get_difficulty() == 0 ) {
5207 add_msg( _( "The %s is taken down." ), tr.name() );
5208 tr.on_disarmed( *this, p );
5209 return;
5210 }
5211
5212 ///\EFFECT_PER increases chance of disarming trap
5213
5214 ///\EFFECT_DEX increases chance of disarming trap
5215
5216 ///\EFFECT_TRAPS increases chance of disarming trap
5217 while( ( rng( 5, 20 ) < g->u.per_cur || rng( 1, 20 ) < g->u.dex_cur ) && roll < 50 ) {
5218 roll++;
5219 }
5220 if( roll >= diff ) {
5221 add_msg( _( "You disarm the trap!" ) );
5222 const int morale_buff = tr.get_avoidance() * 0.4 + tr.get_difficulty() + rng( 0, 4 );
5223 g->u.rem_morale( MORALE_FAILURE );
5224 g->u.add_morale( MORALE_ACCOMPLISHMENT, morale_buff, 40 );
5225 tr.on_disarmed( *this, p );
5226 if( diff > 1.25 * tSkillLevel ) { // failure might have set off trap
5227 g->u.practice( skill_traps, 1.5 * ( diff - tSkillLevel ) );
5228 }
5229 } else if( roll >= diff * .8 ) {
5230 add_msg( _( "You fail to disarm the trap." ) );
5231 const int morale_debuff = -rng( 6, 18 );
5232 g->u.rem_morale( MORALE_ACCOMPLISHMENT );
5233 g->u.add_morale( MORALE_FAILURE, morale_debuff, -40 );
5234 if( diff > 1.25 * tSkillLevel ) {
5235 g->u.practice( skill_traps, 1.5 * ( diff - tSkillLevel ) );
5236 }
5237 } else {
5238 add_msg( m_bad, _( "You fail to disarm the trap, and you set it off!" ) );
5239 const int morale_debuff = -rng( 12, 24 );
5240 g->u.rem_morale( MORALE_ACCOMPLISHMENT );
5241 g->u.add_morale( MORALE_FAILURE, morale_debuff, -40 );
5242 tr.trigger( p, &g->u );
5243 if( diff - roll <= 6 ) {
5244 // Give xp for failing, but not if we failed terribly (in which
5245 // case the trap may not be disarmable).
5246 g->u.practice( skill_traps, 2 * diff );
5247 }
5248 }
5249}
static const skill_id skill_traps("traps")
void add_msg(std::string msg)
Definition: messages.cpp:884
const morale_type MORALE_FAILURE("morale_failure")
const morale_type MORALE_ACCOMPLISHMENT("morale_accomplishment")
Definition: trap.h:86
std::string name() const
Definition: trap.cpp:177
int get_avoidance() const
Whether triggering the trap can be avoid (if greater than 0) and if so, this is compared to dodge ski...
Definition: trap.h:144
void trigger(const tripoint &pos, Creature *creature=nullptr, item *item=nullptr) const
Trigger trap effects.
Definition: trap.cpp:232
bool is_null() const
Whether this is the null-traps, aka no trap at all.
Definition: trap.cpp:245
void on_disarmed(map &m, const tripoint &p) const
Called when a trap at the given point in the map has been disarmed.
Definition: trap.cpp:260
int get_difficulty() const
This is used when disarming the trap.
Definition: trap.h:152

References _, add_msg(), debugmsg, g, trap::get_avoidance(), trap::get_difficulty(), trap::is_null(), m_bad, MORALE_ACCOMPLISHMENT, MORALE_FAILURE, trap::name(), trap::on_disarmed(), rng(), skill_traps, tr_at(), trap::trigger(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by iexamine::trap().

◆ disp_name()

std::string map::disp_name ( const tripoint p)

Definition at line 1325 of file map.cpp.

1326{
1327 return string_format( _( "the %s" ), name( p ) );
1328}

References _, name(), and string_format().

Referenced by vehicle::part_collision().

◆ displace_vehicle()

bool map::displace_vehicle ( vehicle veh,
const tripoint dp 
)

Definition at line 1114 of file map.cpp.

1115{
1116 const tripoint src = veh.global_pos3();
1117
1118 tripoint dst = src + dp;
1119
1120 if( !inbounds( src ) ) {
1121 add_msg( m_debug, "map::displace_vehicle: coordinates out of bounds %d,%d,%d->%d,%d,%d",
1122 src.x, src.y, src.z, dst.x, dst.y, dst.z );
1123 return false;
1124 }
1125
1126 point src_offset;
1127 point dst_offset;
1128 submap *src_submap = get_submap_at( src, src_offset );
1129 submap *dst_submap = get_submap_at( dst, dst_offset );
1130 std::set<int> smzs;
1131
1132 // first, let's find our position in current vehicles vector
1133 size_t our_i = 0;
1134 bool found = false;
1135 for( auto &smap : grid ) {
1136 for( size_t i = 0; i < smap->vehicles.size(); i++ ) {
1137 if( smap->vehicles[i].get() == &veh ) {
1138 our_i = i;
1139 src_submap = smap;
1140 found = true;
1141 break;
1142 }
1143 }
1144 if( found ) {
1145 break;
1146 }
1147 }
1148
1149 if( !found ) {
1150 add_msg( m_debug, "displace_vehicle [%s] failed", veh.name );
1151 return false;
1152 }
1153
1154 // move the vehicle
1155 // don't let it go off grid
1156 if( !inbounds( dst ) ) {
1157 veh.stop();
1158 // Silent debug
1159 dbg( DL::Error ) << "map:displace_vehicle: Stopping vehicle, displaced dp=" << dp;
1160 return true;
1161 }
1162
1163 // Need old coordinates to check for remote control
1164 const bool remote = veh.remote_controlled( g->u );
1165
1166 // record every passenger and pet inside
1167 std::vector<rider_data> riders = veh.get_riders();
1168
1169 bool need_update = false;
1170 bool z_change = false;
1171 int z_to = 0;
1172 // Move passengers and pets
1173 bool complete = false;
1174 // loop until everyone has moved or for each passenger
1175 for( size_t i = 0; !complete && i < riders.size(); i++ ) {
1176 complete = true;
1177 for( rider_data &r : riders ) {
1178 if( r.moved ) {
1179 continue;
1180 }
1181 const int prt = r.prt;
1182
1183 Creature *psg = r.psg;
1184 const tripoint part_pos = veh.global_part_pos3( prt );
1185 if( psg == nullptr ) {
1186 debugmsg( "Empty passenger for part #%d at %d,%d,%d player at %d,%d,%d?",
1187 prt, part_pos.x, part_pos.y, part_pos.z,
1188 g->u.posx(), g->u.posy(), g->u.posz() );
1190 r.moved = true;
1191 continue;
1192 }
1193
1194 if( psg->pos() != part_pos ) {
1195 add_msg( m_debug, "Part/passenger position mismatch: part #%d at %d,%d,%d "
1196 "passenger at %d,%d,%d", prt, part_pos.x, part_pos.y, part_pos.z,
1197 psg->posx(), psg->posy(), psg->posz() );
1198 }
1199 const vehicle_part &veh_part = veh.part( prt );
1200
1201 tripoint next_pos = veh_part.precalc[1];
1202
1203 // Place passenger on the new part location
1204 tripoint psgp( dst + next_pos );
1205 // someone is in the way so try again
1206 if( g->critter_at( psgp ) ) {
1207 complete = false;
1208 continue;
1209 }
1210 if( psg->is_avatar() ) {
1211 // If passenger is you, we need to update the map
1212 need_update = true;
1213 z_change = psgp.z != part_pos.z;
1214 z_to = psgp.z;
1215 }
1216
1217 psg->setpos( psgp );
1218 r.moved = true;
1219 }
1220 }
1221
1222 veh.shed_loose_parts();
1223 smzs = veh.advance_precalc_mounts( dst_offset, src );
1224 if( src_submap != dst_submap ) {
1225 veh.set_submap_moved( tripoint( dst.x / SEEX, dst.y / SEEY, dst.z ) );
1226 auto src_submap_veh_it = src_submap->vehicles.begin() + our_i;
1227 dst_submap->vehicles.push_back( std::move( *src_submap_veh_it ) );
1228 src_submap->vehicles.erase( src_submap_veh_it );
1229 dst_submap->is_uniform = false;
1231 }
1232 if( need_update ) {
1233 g->update_map( g->u );
1234 }
1235 add_vehicle_to_cache( &veh );
1236
1237 if( z_change || src.z != dst.z ) {
1238 if( z_change ) {
1239 g->vertical_shift( z_to );
1240 // vertical moves can flush the caches, so make sure we're still in the cache
1241 add_vehicle_to_cache( &veh );
1242 }
1243 update_vehicle_list( dst_submap, dst.z );
1244 // delete the vehicle from the source z-level vehicle cache set if it is no longer on
1245 // that z-level
1246 if( src.z != dst.z ) {
1247 level_cache &ch2 = get_cache( src.z );
1248 for( const vehicle *elem : ch2.vehicle_list ) {
1249 if( elem == &veh ) {
1250 ch2.vehicle_list.erase( &veh );
1251 ch2.zone_vehicles.erase( &veh );
1252 break;
1253 }
1254 }
1255 }
1257 }
1258
1259 if( remote ) {
1260 // Has to be after update_map or coordinates won't be valid
1261 g->setremoteveh( &veh );
1262 }
1263
1264 //
1265 //global positions of vehicle loot zones have changed.
1266 veh.zones_dirty = true;
1267
1268 for( int vsmz : smzs ) {
1269 on_vehicle_moved( dst.z + vsmz );
1270 }
1271 return true;
1272}
virtual int posy() const =0
virtual int posz() const =0
virtual void setpos(const tripoint &pos)=0
virtual bool is_avatar() const
Definition: creature.h:95
virtual int posx() const =0
void on_vehicle_moved(int smz)
Callback invoked when a vehicle has moved.
Definition: map.cpp:401
void update_vehicle_list(const submap *to, int zlev)
Definition: map.cpp:336
tripoint global_pos3() const
Definition: vehicle.cpp:3104
bool check_is_heli_landed()
void shed_loose_parts()
Definition: vehicle.cpp:6080
std::vector< rider_data > get_riders() const
Definition: vehicle.cpp:3061
void stop(bool update_cache=true)
std::set< int > advance_precalc_mounts(const point &new_pos, const tripoint &src)
Definition: vehicle.cpp:6918
bool remote_controlled(const Character &p) const
Definition: vehicle.cpp:297
void set_submap_moved(const tripoint &p)
Update the submap coordinates and update the tracker info in the overmap (if enabled).
Definition: vehicle.cpp:3119
bool zones_dirty
Definition: vehicle.h:1987
@ m_debug
Definition: enums.h:264
Structure, describing vehicle part (i.e., wheel, seat)
Definition: vehicle.h:185
std::array< tripoint, 2 > precalc
mount translated to face.dir [0] and turn_dir [1]
Definition: vehicle.h:371
int remove_flag(const int flag) noexcept
Definition: vehicle.h:214

References add_msg(), add_vehicle_to_cache(), vehicle::advance_precalc_mounts(), vehicle::check_is_heli_landed(), dbg, debugmsg, Error, g, get_cache(), vehicle::get_riders(), get_submap_at(), vehicle::global_part_pos3(), vehicle::global_pos3(), grid, inbounds(), invalidate_max_populated_zlev(), Creature::is_avatar(), submap::is_uniform, m_debug, avatar_action::move(), vehicle::name, on_vehicle_moved(), vehicle::part(), vehicle_part::passenger_flag, Creature::pos(), Creature::posx(), Creature::posy(), Creature::posz(), vehicle_part::precalc, vehicle::remote_controlled(), vehicle_part::remove_flag(), SEEX, SEEY, vehicle::set_submap_moved(), Creature::setpos(), vehicle::shed_loose_parts(), vehicle::stop(), update_vehicle_list(), level_cache::vehicle_list, submap::vehicles, tripoint::x, tripoint::y, tripoint::z, level_cache::zone_vehicles, and vehicle::zones_dirty.

Referenced by game::grabbed_veh_move(), and move_vehicle().

◆ displace_water()

bool map::displace_water ( const tripoint dp)

Definition at line 1274 of file map.cpp.

1275{
1276 // Check for shallow water
1277 if( has_flag( "SWIMMABLE", p ) && !has_flag( TFLAG_DEEP_WATER, p ) ) {
1278 int dis_places = 0;
1279 int sel_place = 0;
1280 for( int pass = 0; pass < 2; pass++ ) {
1281 // we do 2 passes.
1282 // first, count how many non-water places around
1283 // then choose one within count and fill it with water on second pass
1284 if( pass != 0 ) {
1285 sel_place = rng( 0, dis_places - 1 );
1286 dis_places = 0;
1287 }
1288 for( const tripoint &temp : points_in_radius( p, 1 ) ) {
1289 if( temp != p
1290 || impassable_ter_furn( temp )
1291 || has_flag( TFLAG_DEEP_WATER, temp ) ) {
1292 continue;
1293 }
1294 ter_id ter0 = ter( temp );
1295 if( ter0 == t_water_sh ||
1296 ter0 == t_water_dp || ter0 == t_water_moving_sh || ter0 == t_water_moving_dp ) {
1297 continue;
1298 }
1299 if( pass != 0 && dis_places == sel_place ) {
1300 ter_set( temp, t_water_sh );
1301 ter_set( temp, t_dirt );
1302 return true;
1303 }
1304
1305 dis_places++;
1306 }
1307 }
1308 }
1309 return false;
1310}
ter_id t_water_moving_dp
Definition: mapdata.cpp:693
ter_id t_water_moving_sh
Definition: mapdata.cpp:693
ter_id t_water_dp
Definition: mapdata.cpp:693
ter_id t_water_sh
Definition: mapdata.cpp:693

References has_flag(), impassable_ter_furn(), points_in_radius(), rng(), t_dirt, t_water_dp, t_water_moving_dp, t_water_moving_sh, t_water_sh, ter(), ter_set(), and TFLAG_DEEP_WATER.

Referenced by move_vehicle().

◆ do_vehicle_caching()

void map::do_vehicle_caching ( int  z)

Definition at line 8017 of file map.cpp.

8018{
8019 level_cache &ch = get_cache( z );
8020 for( vehicle *v : ch.vehicle_list ) {
8021 for( const vpart_reference &vp : v->get_all_parts() ) {
8022 const tripoint &part_pos = v->global_part_pos3( vp.part() );
8023 if( !inbounds( part_pos.xy() ) ) {
8024 continue;
8025 }
8026 vehicle_caching_internal( get_cache( part_pos.z ), vp, v );
8027 if( part_pos.z < OVERMAP_HEIGHT ) {
8028 vehicle_caching_internal_above( get_cache( part_pos.z + 1 ), vp, v );
8029 }
8030 }
8031 }
8032}
static void vehicle_caching_internal_above(level_cache &zch_above, const vpart_reference &vp, vehicle *v)
Definition: map.cpp:8008
static void vehicle_caching_internal(level_cache &zch, const vpart_reference &vp, vehicle *v)
Definition: map.cpp:7979

References vehicle::get_all_parts(), get_cache(), vehicle::global_part_pos3(), inbounds(), OVERMAP_HEIGHT, vehicle_caching_internal(), vehicle_caching_internal_above(), level_cache::vehicle_list, tripoint::xy(), and tripoint::z.

Referenced by build_map_cache().

◆ dont_draw_lower_floor()

bool map::dont_draw_lower_floor ( const tripoint p)

Definition at line 5829 of file map.cpp.

5830{
5831 return !zlevels || p.z <= -OVERMAP_DEPTH ||
5833}
@ TFLAG_Z_TRANSPARENT
Definition: mapdata.h:321

References has_flag(), OVERMAP_DEPTH, TFLAG_NO_FLOOR, TFLAG_Z_TRANSPARENT, tripoint::z, and zlevels.

◆ draw()

void map::draw ( const catacurses::window w,
const tripoint center 
)

Draw a visible part of the map into w.

This method uses g->u.posx()/posy() for visibility calculations, so it can not be used for anything but the player's viewport. Likewise, only g->m and maps with equivalent coordinates can be used, as other maps would have coordinate systems incompatible with g->u.posx()

Parameters
wWindow we are drawing in
centerThe coordinate of the center of the viewport, this can be different from the player coordinate.

Definition at line 5670 of file map.cpp.

5671{
5672 // We only need to draw anything if we're not in tiles mode.
5673 if( is_draw_tiles_mode() ) {
5674 return;
5675 }
5676
5677 g->reset_light_level();
5678
5681
5682 const auto &visibility_cache = get_cache_ref( center.z ).visibility_cache;
5683
5684 int wnd_h = getmaxy( w );
5685 int wnd_w = getmaxx( w );
5686 const tripoint offs = center - tripoint( wnd_w / 2, wnd_h / 2, 0 );
5687
5688 // Map memory should be at least the size of the view range
5689 // so that new tiles can be memorized, and at least the size of the terminal
5690 // since displayed area may be bigger than view range.
5691 const point min_mm_reg = point(
5692 std::min( 0, offs.x ),
5693 std::min( 0, offs.y )
5694 );
5695 const point max_mm_reg = point(
5696 std::max( MAPSIZE_X, offs.x + wnd_w ),
5697 std::max( MAPSIZE_Y, offs.y + wnd_h )
5698 );
5699 g->u.prepare_map_memory_region(
5700 g->m.getabs( tripoint( min_mm_reg, center.z ) ),
5701 g->m.getabs( tripoint( max_mm_reg, center.z ) )
5702 );
5703
5704 const auto draw_background = [&]( const tripoint & p ) {
5705 int sym = ' ';
5706 nc_color col = c_black;
5707 if( has_memory_at( p ) ) {
5708 sym = get_memory_at( p );
5709 col = c_brown;
5710 }
5711 wputch( w, col, sym );
5712 };
5713
5714 const auto draw_vision_effect = [&]( const visibility_type vis ) -> bool {
5715 int sym = '#';
5716 nc_color col;
5717 switch( vis )
5718 {
5719 case VIS_LIT:
5720 // can only tell that this square is bright
5721 col = c_light_gray;
5722 break;
5723 case VIS_BOOMER:
5724 col = c_pink;
5725 break;
5726 case VIS_BOOMER_DARK:
5727 col = c_magenta;
5728 break;
5729 default:
5730 return false;
5731 }
5732 wputch( w, col, sym );
5733 return true;
5734 };
5735
5736 drawsq_params params = drawsq_params().memorize( true );
5737 for( int wy = 0; wy < wnd_h; wy++ ) {
5738 for( int wx = 0; wx < wnd_w; wx++ ) {
5739 wmove( w, point( wx, wy ) );
5740 const tripoint p = offs + tripoint( wx, wy, 0 );
5741 if( !inbounds( p ) ) {
5742 draw_background( p );
5743 continue;
5744 }
5745
5746 const lit_level lighting = visibility_cache[p.x][p.y];
5747 const visibility_type vis = get_visibility( lighting, cache );
5748
5749 if( draw_vision_effect( vis ) ) {
5750 continue;
5751 }
5752
5753 if( vis == VIS_HIDDEN || vis == VIS_DARK ) {
5754 draw_background( p );
5755 continue;
5756 }
5757
5758 const maptile curr_maptile = maptile_at_internal( p );
5759 params
5760 .low_light( lighting == lit_level::LOW )
5761 .bright_light( lighting == lit_level::BRIGHT );
5762 if( draw_maptile( w, p, curr_maptile, params ) ) {
5763 continue;
5764 }
5765 const maptile tile_below = maptile_at_internal( p - tripoint_above );
5766 draw_from_above( w, tripoint( p.xy(), p.z - 1 ), tile_below, params );
5767 }
5768 }
5769
5770 // Memorize off-screen tiles
5771 half_open_rectangle<point> display( offs.xy(), offs.xy() + point( wnd_w, wnd_h ) );
5772 drawsq_params mm_params = drawsq_params().memorize( true ).output( false );
5773 for( int y = 0; y < MAPSIZE_Y; y++ ) {
5774 for( int x = 0; x < MAPSIZE_X; x++ ) {
5775 const tripoint p( x, y, center.z );
5776 if( display.contains( p.xy() ) ) {
5777 // Have been memorized during display loop
5778 continue;
5779 }
5780
5781 const lit_level lighting = visibility_cache[p.x][p.y];
5782 const visibility_type vis = get_visibility( lighting, cache );
5783
5784 if( vis != VIS_CLEAR ) {
5785 continue;
5786 }
5787
5788 const maptile curr_maptile = maptile_at_internal( p );
5789 mm_params
5790 .low_light( lighting == lit_level::LOW )
5791 .bright_light( lighting == lit_level::BRIGHT );
5792
5793 draw_maptile( w, p, curr_maptile, mm_params );
5794 }
5795 }
5796}
bool draw_maptile(const catacurses::window &w, const tripoint &p, const maptile &tile, const drawsq_params &params) const
Internal version of the drawsq.
Definition: map.cpp:5835
visibility_type get_visibility(lit_level ll, const visibility_variables &cache) const
Definition: map.cpp:5620
void draw_from_above(const catacurses::window &w, const tripoint &p, const maptile &tile, const drawsq_params &params) const
Draws the tile as seen from above.
Definition: map.cpp:6026
const visibility_variables & get_visibility_variables_cache() const
Definition: map.cpp:5615
void update_visibility_cache(int zlev)
Definition: map.cpp:5574
maptile maptile_at_internal(const tripoint &p) const
Definition: map.cpp:215
#define c_light_gray
Definition: color.h:19
#define c_black
Definition: color.h:17
#define c_magenta
Definition: color.h:25
#define c_brown
Definition: color.h:26
#define c_pink
Definition: color.h:31
visibility_type
Definition: enums.h:57
@ VIS_CLEAR
Definition: enums.h:59
@ VIS_BOOMER
Definition: enums.h:61
@ VIS_DARK
Definition: enums.h:62
@ VIS_BOOMER_DARK
Definition: enums.h:63
@ VIS_HIDDEN
Definition: enums.h:58
@ VIS_LIT
Definition: enums.h:60
lit_level
Definition: lightmap.h:43
static bool has_memory_at(const tripoint &p)
Definition: map.cpp:5653
static int get_memory_at(const tripoint &p)
Definition: map.cpp:5662
int getmaxx(const window &win)
Definition: ncurses_def.cpp:58
int getmaxy(const window &win)
Definition: ncurses_def.cpp:63
void wmove(const window &win, const point &p)
Definition: ncurses_def.cpp:98
static tripoint_abs_omt display(const tripoint_abs_omt &orig, const draw_data_t &data=draw_data_t())
bool is_draw_tiles_mode()
Check whether we're in tile drawing mode.
Definition: output.cpp:2029
void wputch(const catacurses::window &w, nc_color FG, int ch)
Definition: output.cpp:470
static constexpr tripoint tripoint_above
Definition: point.h:294
Draw parameters used by map::drawsq() and similar methods.
Definition: map.h:176
constexpr drawsq_params & bright_light(bool v)
Whether tile is in bright light.
Definition: map.h:236
constexpr drawsq_params & output(bool v)
HACK: Whether the tile should be printed.
Definition: map.h:265
constexpr drawsq_params & memorize(bool v)
Whether the tile should be memorized.
Definition: map.h:250
constexpr drawsq_params & low_light(bool v)
Whether tile is low light, and should be drawn with muted color.
Definition: map.h:222
lit_level visibility_cache[MAPSIZE_X][MAPSIZE_Y]
Definition: map.h:338
A wrapper for a submap point.
Definition: submap.h:267

References BRIGHT, drawsq_params::bright_light(), c_black, c_brown, c_light_gray, c_magenta, c_pink, center, overmap_ui::display(), draw_from_above(), draw_maptile(), g, get_cache_ref(), get_memory_at(), get_visibility(), get_visibility_variables_cache(), catacurses::getmaxx(), catacurses::getmaxy(), has_memory_at(), inbounds(), is_draw_tiles_mode(), LOW, drawsq_params::low_light(), MAPSIZE_X, MAPSIZE_Y, maptile_at_internal(), drawsq_params::memorize(), drawsq_params::output(), tripoint_above, update_visibility_cache(), VIS_BOOMER, VIS_BOOMER_DARK, VIS_CLEAR, VIS_DARK, VIS_HIDDEN, VIS_LIT, level_cache::visibility_cache, catacurses::wmove(), wputch(), tripoint::x, tripoint::xy(), tripoint::y, and tripoint::z.

Referenced by advanced_inventory::draw_minimap(), and game::draw_ter().

◆ draw_anthill()

void map::draw_anthill ( mapgendata dat)
protected

Definition at line 5025 of file mapgen.cpp.

5026{
5027 const oter_id &terrain_type = dat.terrain_type();
5028 if( terrain_type == "anthill" || terrain_type == "acid_anthill" ) {
5029 for( int i = 0; i < SEEX * 2; i++ ) {
5030 for( int j = 0; j < SEEY * 2; j++ ) {
5031 if( i < 8 || j < 8 || i > SEEX * 2 - 9 || j > SEEY * 2 - 9 ) {
5032 ter_set( point( i, j ), dat.groundcover() );
5033 } else if( ( i == 11 || i == 12 ) && ( j == 11 || j == 12 ) ) {
5034 ter_set( point( i, j ), t_slope_down );
5035 } else {
5036 ter_set( point( i, j ), t_dirtmound );
5037 }
5038 }
5039 }
5040 }
5041}
const oter_id & terrain_type() const
Definition: mapgendata.h:87
ter_id groundcover()
Definition: mapgendata.cpp:141
ter_id t_slope_down
Definition: mapdata.cpp:718
ter_id t_dirtmound
Definition: mapdata.cpp:625

References mapgendata::groundcover(), SEEX, SEEY, t_dirtmound, t_slope_down, ter_set(), and mapgendata::terrain_type().

Referenced by draw_map().

◆ draw_circle_furn()

void map::draw_circle_furn ( const furn_id type,
const point p,
int  rad 
)

Definition at line 8252 of file map.cpp.

8253{
8254 draw_circle( [this, type]( const point & q ) {
8255 this->furn_set( q, type );
8256 }, p, rad );
8257}
void draw_circle(std::function< void(const point &)>set, const rl_vec2d &p, double rad)

References draw_circle(), furn_set(), and type.

Referenced by circle_furn().

◆ draw_circle_ter() [1/2]

void map::draw_circle_ter ( const ter_id type,
const point p,
int  rad 
)

Definition at line 8245 of file map.cpp.

8246{
8247 draw_circle( [this, type]( const point & q ) {
8248 this->ter_set( q, type );
8249 }, p, rad );
8250}

References draw_circle(), ter_set(), and type.

◆ draw_circle_ter() [2/2]

void map::draw_circle_ter ( const ter_id type,
const rl_vec2d p,
double  rad 
)

Definition at line 8238 of file map.cpp.

8239{
8240 draw_circle( [this, type]( const point & q ) {
8241 this->ter_set( q, type );
8242 }, p, rad );
8243}

References draw_circle(), ter_set(), and type.

Referenced by circle().

◆ draw_connections()

void map::draw_connections ( mapgendata dat)
protected

Definition at line 5235 of file mapgen.cpp.

5236{
5237 const oter_id &terrain_type = dat.terrain_type();
5238 if( is_ot_match( "subway", terrain_type,
5239 ot_match_type::type ) ) { // FUUUUU it's IF ELIF ELIF ELIF's mini-me =[
5240 if( is_ot_match( "sewer", dat.north(), ot_match_type::type ) &&
5241 !connects_to( terrain_type, 0 ) ) {
5242 if( connects_to( dat.north(), 2 ) ) {
5243 for( int i = SEEX - 2; i < SEEX + 2; i++ ) {
5244 for( int j = 0; j < SEEY; j++ ) {
5245 ter_set( point( i, j ), t_sewage );
5246 }
5247 }
5248 } else {
5249 for( int j = 0; j < 3; j++ ) {
5250 ter_set( point( SEEX, j ), t_rock_floor );
5251 ter_set( point( SEEX - 1, j ), t_rock_floor );
5252 }
5253 ter_set( point( SEEX, 3 ), t_door_metal_c );
5254 ter_set( point( SEEX - 1, 3 ), t_door_metal_c );
5255 }
5256 }
5257 if( is_ot_match( "sewer", dat.east(), ot_match_type::type ) &&
5258 !connects_to( terrain_type, 1 ) ) {
5259 if( connects_to( dat.east(), 3 ) ) {
5260 for( int i = SEEX; i < SEEX * 2; i++ ) {
5261 for( int j = SEEY - 2; j < SEEY + 2; j++ ) {
5262 ter_set( point( i, j ), t_sewage );
5263 }
5264 }
5265 } else {
5266 for( int i = SEEX * 2 - 3; i < SEEX * 2; i++ ) {
5267 ter_set( point( i, SEEY ), t_rock_floor );
5268 ter_set( point( i, SEEY - 1 ), t_rock_floor );
5269 }
5270 ter_set( point( SEEX * 2 - 4, SEEY ), t_door_metal_c );
5271 ter_set( point( SEEX * 2 - 4, SEEY - 1 ), t_door_metal_c );
5272 }
5273 }
5274 if( is_ot_match( "sewer", dat.south(), ot_match_type::type ) &&
5275 !connects_to( terrain_type, 2 ) ) {
5276 if( connects_to( dat.south(), 0 ) ) {
5277 for( int i = SEEX - 2; i < SEEX + 2; i++ ) {
5278 for( int j = SEEY; j < SEEY * 2; j++ ) {
5279 ter_set( point( i, j ), t_sewage );
5280 }
5281 }
5282 } else {
5283 for( int j = SEEY * 2 - 3; j < SEEY * 2; j++ ) {
5284 ter_set( point( SEEX, j ), t_rock_floor );
5285 ter_set( point( SEEX - 1, j ), t_rock_floor );
5286 }
5287 ter_set( point( SEEX, SEEY * 2 - 4 ), t_door_metal_c );
5288 ter_set( point( SEEX - 1, SEEY * 2 - 4 ), t_door_metal_c );
5289 }
5290 }
5291 if( is_ot_match( "sewer", dat.west(), ot_match_type::type ) &&
5292 !connects_to( terrain_type, 3 ) ) {
5293 if( connects_to( dat.west(), 1 ) ) {
5294 for( int i = 0; i < SEEX; i++ ) {
5295 for( int j = SEEY - 2; j < SEEY + 2; j++ ) {
5296 ter_set( point( i, j ), t_sewage );
5297 }
5298 }
5299 } else {
5300 for( int i = 0; i < 3; i++ ) {
5301 ter_set( point( i, SEEY ), t_rock_floor );
5302 ter_set( point( i, SEEY - 1 ), t_rock_floor );
5303 }
5304 ter_set( point( 3, SEEY ), t_door_metal_c );
5305 ter_set( point( 3, SEEY - 1 ), t_door_metal_c );
5306 }
5307 }
5308 } else if( is_ot_match( "sewer", terrain_type, ot_match_type::type ) ) {
5309 if( dat.above() == "road_nesw_manhole" ) {
5310 ter_set( point( rng( SEEX - 2, SEEX + 1 ), rng( SEEY - 2, SEEY + 1 ) ), t_ladder_up );
5311 }
5312 if( is_ot_match( "subway", dat.north(), ot_match_type::type ) &&
5313 !connects_to( terrain_type, 0 ) ) {
5314 for( int j = 0; j < SEEY - 3; j++ ) {
5315 ter_set( point( SEEX, j ), t_rock_floor );
5316 ter_set( point( SEEX - 1, j ), t_rock_floor );
5317 }
5318 ter_set( point( SEEX, SEEY - 3 ), t_door_metal_c );
5319 ter_set( point( SEEX - 1, SEEY - 3 ), t_door_metal_c );
5320 }
5321 if( is_ot_match( "subway", dat.east(), ot_match_type::type ) &&
5322 !connects_to( terrain_type, 1 ) ) {
5323 for( int i = SEEX + 3; i < SEEX * 2; i++ ) {
5324 ter_set( point( i, SEEY ), t_rock_floor );
5325 ter_set( point( i, SEEY - 1 ), t_rock_floor );
5326 }
5327 ter_set( point( SEEX + 2, SEEY ), t_door_metal_c );
5328 ter_set( point( SEEX + 2, SEEY - 1 ), t_door_metal_c );
5329 }
5330 if( is_ot_match( "subway", dat.south(), ot_match_type::type ) &&
5331 !connects_to( terrain_type, 2 ) ) {
5332 for( int j = SEEY + 3; j < SEEY * 2; j++ ) {
5333 ter_set( point( SEEX, j ), t_rock_floor );
5334 ter_set( point( SEEX - 1, j ), t_rock_floor );
5335 }
5336 ter_set( point( SEEX, SEEY + 2 ), t_door_metal_c );
5337 ter_set( point( SEEX - 1, SEEY + 2 ), t_door_metal_c );
5338 }
5339 if( is_ot_match( "subway", dat.west(), ot_match_type::type ) &&
5340 !connects_to( terrain_type, 3 ) ) {
5341 for( int i = 0; i < SEEX - 3; i++ ) {
5342 ter_set( point( i, SEEY ), t_rock_floor );
5343 ter_set( point( i, SEEY - 1 ), t_rock_floor );
5344 }
5345 ter_set( point( SEEX - 3, SEEY ), t_door_metal_c );
5346 ter_set( point( SEEX - 3, SEEY - 1 ), t_door_metal_c );
5347 }
5348 } else if( is_ot_match( "ants", terrain_type, ot_match_type::type ) ) {
5349 if( dat.above() == "anthill" ) {
5350 if( const auto p = random_point( *this, [this]( const tripoint & n ) {
5351 return ter( n ) == t_rock_floor;
5352 } ) ) {
5353 ter_set( *p, t_slope_up );
5354 }
5355 }
5356 }
5357
5358 // finally, any terrain with SIDEWALKS should contribute sidewalks to neighboring diagonal roads
5359 if( terrain_type->has_flag( has_sidewalk ) ) {
5360 for( int dir = 4; dir < 8; dir++ ) { // NE SE SW NW
5361 bool n_roads_nesw[4] = {};
5362 int n_num_dirs = terrain_type_to_nesw_array( oter_id( dat.t_nesw[dir] ), n_roads_nesw );
5363 // only handle diagonal neighbors
5364 if( n_num_dirs == 2 &&
5365 n_roads_nesw[( ( dir - 4 ) + 3 ) % 4] &&
5366 n_roads_nesw[( ( dir - 4 ) + 2 ) % 4] ) {
5367 // make drawing simpler by rotating the map back and forth
5368 rotate( 4 - ( dir - 4 ) );
5369 // draw a small triangle of sidewalk in the northeast corner
5370 for( int y = 0; y < 4; y++ ) {
5371 for( int x = SEEX * 2 - 4; x < SEEX * 2; x++ ) {
5372 if( x - y > SEEX * 2 - 4 ) {
5373 // TODO: more discriminating conditions
5374 if( ter( point( x, y ) ) == t_grass || ter( point( x, y ) ) == t_dirt ||
5375 ter( point( x, y ) ) == t_shrub ) {
5376 ter_set( point( x, y ), t_sidewalk );
5377 }
5378 }
5379 }
5380 }
5381 rotate( ( dir - 4 ) );
5382 }
5383 }
5384 }
5385
5387}
void rotate(int turns, bool setpos_safe=false)
Rotates this map, and all of its contents, by the specified multiple of 90 degrees.
Definition: mapgen.cpp:5798
const oter_id & above() const
Definition: mapgendata.h:131
const oter_id & north() const
Definition: mapgendata.h:107
const oter_id & west() const
Definition: mapgendata.h:116
const oter_id & south() const
Definition: mapgendata.h:113
oter_id t_nesw[8]
Definition: mapgendata.h:45
const oter_id & east() const
Definition: mapgendata.h:110
cata::optional< tripoint > random_point(const map &m, const std::function< bool(const tripoint &)> &predicate)
Same as other random_point with a range enclosing all valid points of the map.
ter_id t_grass
Definition: mapdata.cpp:628
ter_id t_sewage
Definition: mapdata.cpp:694
ter_id t_slope_up
Definition: mapdata.cpp:719
ter_id t_ladder_up
Definition: mapdata.cpp:718
ter_id t_shrub
Definition: mapdata.cpp:683
ter_id t_sidewalk
Definition: mapdata.cpp:630
ter_id t_door_metal_c
Definition: mapdata.cpp:662
bool connects_to(const oter_id &there, int dir)
Definition: mapgen.cpp:5900
void resolve_regional_terrain_and_furniture(const mapgendata &dat)
int terrain_type_to_nesw_array(oter_id terrain_type, bool array[4])
@ has_sidewalk
Definition: omdata.h:94
bool is_ot_match(const std::string &name, const oter_id &oter, const ot_match_type match_type)
Determine if the provided name is a match with the provided overmap terrain based on the specified ma...
Definition: overmap.cpp:544
bool has_flag(oter_flags flag) const
Definition: omdata.h:262

References mapgendata::above(), connects_to(), mapgendata::east(), oter_t::has_flag(), has_sidewalk, is_ot_match(), mapgendata::north(), oter_id, random_point(), resolve_regional_terrain_and_furniture(), rng(), rotate(), SEEX, SEEY, mapgendata::south(), t_dirt, t_door_metal_c, t_grass, t_ladder_up, mapgendata::t_nesw, t_rock_floor, t_sewage, t_shrub, t_sidewalk, t_slope_up, ter(), ter_set(), mapgendata::terrain_type(), terrain_type_to_nesw_array(), type, and mapgendata::west().

Referenced by draw_map().

◆ draw_fill_background() [1/3]

void map::draw_fill_background ( const ter_id type)

Definition at line 8167 of file map.cpp.

8168{
8169 // Need to explicitly set caches dirty - set_ter would do it before
8174
8175 // Fill each submap rather than each tile
8176 for( int gridx = 0; gridx < my_MAPSIZE; gridx++ ) {
8177 for( int gridy = 0; gridy < my_MAPSIZE; gridy++ ) {
8178 auto sm = get_submap_at_grid( {gridx, gridy} );
8179 sm->is_uniform = true;
8180 sm->set_all_ter( type );
8181 }
8182 }
8183}
void set_outside_cache_dirty(const int zlev)
Definition: map.h:430

References abs_sub, get_submap_at_grid(), my_MAPSIZE, set_outside_cache_dirty(), set_pathfinding_cache_dirty(), set_seen_cache_dirty(), set_transparency_cache_dirty(), coords::sm, type, and tripoint::z.

Referenced by fill_background(), mapgendata::fill_groundcover(), mapgen_function_json::generate(), and mapgen_forest().

◆ draw_fill_background() [2/3]

void map::draw_fill_background ( const weighted_int_list< ter_id > &  f)

Definition at line 8189 of file map.cpp.

8190{
8192}
void draw_square_ter(const ter_id &type, const point &p1, const point &p2)
Definition: map.cpp:8194

References draw_square_ter(), my_MAPSIZE, point_zero, SEEX, and SEEY.

◆ draw_fill_background() [3/3]

void map::draw_fill_background ( ter_id(*)()  f)

Definition at line 8185 of file map.cpp.

8186{
8188}

References draw_square_ter(), my_MAPSIZE, point_zero, SEEX, and SEEY.

◆ draw_from_above()

void map::draw_from_above ( const catacurses::window w,
const tripoint p,
const maptile tile,
const drawsq_params params 
) const
private

Draws the tile as seen from above.

Definition at line 6026 of file map.cpp.

6028{
6029 static const int AUTO_WALL_PLACEHOLDER = 2; // this should never appear as a real symbol!
6030
6031 nc_color tercol = c_dark_gray;
6032 int sym = ' ';
6033
6034 const ter_t &curr_ter = curr_tile.get_ter_t();
6035 const furn_t &curr_furn = curr_tile.get_furn_t();
6036 int part_below;
6037 const vehicle *veh;
6038 if( curr_furn.has_flag( TFLAG_SEEN_FROM_ABOVE ) ) {
6039 sym = curr_furn.symbol();
6040 tercol = curr_furn.color();
6041 } else if( curr_furn.movecost < 0 ) {
6042 sym = '.';
6043 tercol = curr_furn.color();
6044 } else if( ( veh = veh_at_internal( p, part_below ) ) != nullptr ) {
6045 const int roof = veh->roof_at_part( part_below );
6046 const int displayed_part = roof >= 0 ? roof : part_below;
6047 sym = special_symbol( veh->face.dir_symbol( veh->part_sym( displayed_part, true ) ) );
6048 tercol = ( roof >= 0 ||
6049 vpart_position( const_cast<vehicle &>( *veh ),
6050 part_below ).obstacle_at_part() ) ? c_light_gray : c_light_gray_cyan;
6051 } else if( curr_ter.has_flag( TFLAG_SEEN_FROM_ABOVE ) ) {
6052 if( curr_ter.has_flag( TFLAG_AUTO_WALL_SYMBOL ) ) {
6053 sym = AUTO_WALL_PLACEHOLDER;
6054 } else if( curr_ter.has_flag( TFLAG_RAMP ) ) {
6055 sym = '>';
6056 } else {
6057 sym = curr_ter.symbol();
6058 }
6059 tercol = curr_ter.color();
6060 } else if( curr_ter.movecost == 0 ) {
6061 sym = '.';
6062 tercol = curr_ter.color();
6063 } else if( !curr_ter.has_flag( TFLAG_NO_FLOOR ) ) {
6064 sym = '.';
6065 if( curr_ter.color() != c_cyan ) {
6066 // Need a special case here, it doesn't cyanize well
6067 tercol = cyan_background( curr_ter.color() );
6068 } else {
6069 tercol = c_black_cyan;
6070 }
6071 } else {
6072 sym = curr_ter.symbol();
6073 tercol = curr_ter.color();
6074 }
6075
6076 if( sym == AUTO_WALL_PLACEHOLDER ) {
6077 sym = determine_wall_corner( p );
6078 }
6079
6080 const auto u_vision = g->u.get_vision_modes();
6081 if( u_vision[BOOMERED] ) {
6082 tercol = c_magenta;
6083 } else if( u_vision[NV_GOGGLES] ) {
6084 tercol = params.bright_light() ? c_white : c_light_green;
6085 } else if( params.low_light() ) {
6086 tercol = c_dark_gray;
6087 } else if( u_vision[DARKNESS] ) {
6088 tercol = c_dark_gray;
6089 }
6090
6091 if( params.highlight() ) {
6092 tercol = invert_color( tercol );
6093 }
6094
6095 if( params.output() ) {
6096 wputch( w, tercol, sym );
6097 }
6098}
@ DARKNESS
Definition: character.h:88
@ NV_GOGGLES
Definition: character.h:84
@ BOOMERED
Definition: character.h:87
int determine_wall_corner(const tripoint &p) const
Definition: map.cpp:7701
vehicle * veh_at_internal(const tripoint &p, int &part_num)
Definition: map.cpp:1039
int dir_symbol(int sym) const
Definition: tileray.cpp:113
char part_sym(int p, bool exact=false) const
int roof_at_part(int p) const
Definition: vehicle.cpp:2978
tileray face
Definition: vehicle.h:1928
cata::optional< vpart_reference > obstacle_at_part() const
Returns the obstacle that exists at this point of the vehicle (if any).
Definition: vehicle.cpp:2438
nc_color invert_color(const nc_color &c)
Definition: color.cpp:503
nc_color cyan_background(const nc_color &c)
Definition: color.cpp:545
#define c_white
Definition: color.h:18
#define c_light_green
Definition: color.h:28
#define c_dark_gray
Definition: color.h:20
#define c_black_cyan
Definition: color.h:154
#define c_cyan
Definition: color.h:24
#define c_light_gray_cyan
Definition: color.h:156
@ TFLAG_AUTO_WALL_SYMBOL
Definition: mapdata.h:305
@ TFLAG_SEEN_FROM_ABOVE
Definition: mapdata.h:311
int special_symbol(int sym)
Definition: output.cpp:1095
constexpr drawsq_params & highlight(bool v)
Highlight the tile.
Definition: map.h:194
nc_color color() const
Definition: mapdata.cpp:555

References BOOMERED, drawsq_params::bright_light(), c_black_cyan, c_cyan, c_dark_gray, c_light_gray, c_light_gray_cyan, c_light_green, c_magenta, c_white, map_data_common_t::color(), cyan_background(), DARKNESS, determine_wall_corner(), tileray::dir_symbol(), vehicle::face, g, maptile::get_furn_t(), maptile::get_ter_t(), map_data_common_t::has_flag(), drawsq_params::highlight(), invert_color(), drawsq_params::low_light(), map_data_common_t::movecost, NV_GOGGLES, vpart_position::obstacle_at_part(), drawsq_params::output(), vehicle::part_sym(), vehicle::roof_at_part(), special_symbol(), map_data_common_t::symbol(), TFLAG_AUTO_WALL_SYMBOL, TFLAG_NO_FLOOR, TFLAG_RAMP, TFLAG_SEEN_FROM_ABOVE, veh_at_internal(), and wputch().

Referenced by draw(), and drawsq().

◆ draw_lab()

void map::draw_lab ( mapgendata dat)
protected

Definition at line 3515 of file mapgen.cpp.

3516{
3517 const oter_id &terrain_type = dat.terrain_type();
3518 // To distinguish between types of labs
3519 bool ice_lab = true;
3520 bool central_lab = false;
3521 bool tower_lab = false;
3522
3523 point p2;
3524
3525 int lw = 0;
3526 int rw = 0;
3527 int tw = 0;
3528 int bw = 0;
3529
3530 if( terrain_type == "lab" || terrain_type == "lab_stairs" || terrain_type == "lab_core" ||
3531 terrain_type == "ants_lab" || terrain_type == "ants_lab_stairs" ||
3532 terrain_type == "ice_lab" || terrain_type == "ice_lab_stairs" ||
3533 terrain_type == "ice_lab_core" ||
3534 terrain_type == "central_lab" || terrain_type == "central_lab_stairs" ||
3535 terrain_type == "central_lab_core" ||
3536 terrain_type == "tower_lab" || terrain_type == "tower_lab_stairs" ) {
3537
3538 ice_lab = is_ot_match( "ice_lab", terrain_type, ot_match_type::prefix );
3539 central_lab = is_ot_match( "central_lab", terrain_type, ot_match_type::prefix );
3540 tower_lab = is_ot_match( "tower_lab", terrain_type, ot_match_type::prefix );
3541
3542 if( ice_lab ) {
3543 int temperature = -20 + 30 * ( dat.zlevel() );
3545 set_temperature( p2 + point( SEEX, 0 ), temperature );
3546 set_temperature( p2 + point( 0, SEEY ), temperature );
3548 }
3549
3550 // Check for adjacent sewers; used below
3551 tw = 0;
3552 rw = 0;
3553 bw = 0;
3554 lw = 0;
3555 if( is_ot_match( "sewer", dat.north(), ot_match_type::type ) && connects_to( dat.north(), 2 ) ) {
3556 tw = SOUTH_EDGE + 1;
3557 }
3558 if( is_ot_match( "sewer", dat.east(), ot_match_type::type ) && connects_to( dat.east(), 3 ) ) {
3559 rw = EAST_EDGE + 1;
3560 }
3561 if( is_ot_match( "sewer", dat.south(), ot_match_type::type ) && connects_to( dat.south(), 0 ) ) {
3562 bw = SOUTH_EDGE + 1;
3563 }
3564 if( is_ot_match( "sewer", dat.west(), ot_match_type::type ) && connects_to( dat.west(), 1 ) ) {
3565 lw = EAST_EDGE + 1;
3566 }
3567 if( dat.zlevel() == 0 ) { // We're on ground level
3568 for( int i = 0; i < SEEX * 2; i++ ) {
3569 for( int j = 0; j < SEEY * 2; j++ ) {
3570 if( i <= 1 || i >= SEEX * 2 - 2 ||
3571 ( j > 1 && j < SEEY * 2 - 2 && ( i == SEEX - 2 || i == SEEX + 1 ) ) ) {
3572 ter_set( point( i, j ), t_concrete_wall );
3573 } else if( j <= 1 || j >= SEEY * 2 - 2 ) {
3574 ter_set( point( i, j ), t_concrete_wall );
3575 } else {
3576 ter_set( point( i, j ), t_floor );
3577 }
3578 }
3579 }
3580 ter_set( point( SEEX - 1, 0 ), t_door_metal_locked );
3581 ter_set( point( SEEX - 1, 1 ), t_floor );
3583 ter_set( point( SEEX, 1 ), t_floor );
3584 ter_set( point( SEEX - 2 + rng( 0, 1 ) * 3, 0 ), t_card_science );
3585 ter_set( point( SEEX - 2, SEEY ), t_door_metal_c );
3586 ter_set( point( SEEX + 1, SEEY ), t_door_metal_c );
3587 ter_set( point( SEEX - 2, SEEY - 1 ), t_door_metal_c );
3588 ter_set( point( SEEX + 1, SEEY - 1 ), t_door_metal_c );
3589 ter_set( point( SEEX - 1, SEEY * 2 - 3 ), t_stairs_down );
3590 ter_set( point( SEEX, SEEY * 2 - 3 ), t_stairs_down );
3591 science_room( this, point( 2, 2 ), point( SEEX - 3, SEEY * 2 - 3 ), dat.zlevel(), 1 );
3592 science_room( this, point( SEEX + 2, 2 ), point( SEEX * 2 - 3, SEEY * 2 - 3 ), dat.zlevel(), 3 );
3593
3594 place_spawns( GROUP_TURRET, 1, point( SEEX, 5 ), point( SEEX, 5 ), 1, true );
3595
3596 if( is_ot_match( "road", dat.east(), ot_match_type::type ) ) {
3597 rotate( 1 );
3598 } else if( is_ot_match( "road", dat.south(), ot_match_type::type ) ) {
3599 rotate( 2 );
3600 } else if( is_ot_match( "road", dat.west(), ot_match_type::type ) ) {
3601 rotate( 3 );
3602 }
3603 } else if( tw != 0 || rw != 0 || lw != 0 || bw != 0 ) { // Sewers!
3604 for( int i = 0; i < SEEX * 2; i++ ) {
3605 for( int j = 0; j < SEEY * 2; j++ ) {
3606 ter_set( point( i, j ), t_thconc_floor );
3607 if( ( ( i < lw || i > EAST_EDGE - rw ) && j > SEEY - 3 && j < SEEY + 2 ) ||
3608 ( ( j < tw || j > SOUTH_EDGE - bw ) && i > SEEX - 3 && i < SEEX + 2 ) ) {
3609 ter_set( point( i, j ), t_sewage );
3610 }
3611 if( ( i == 0 && is_ot_match( "lab", dat.east(), ot_match_type::contains ) ) || i == EAST_EDGE ) {
3612 if( ter( point( i, j ) ) == t_sewage ) {
3613 ter_set( point( i, j ), t_bars );
3614 } else if( j == SEEY - 1 || j == SEEY ) {
3615 ter_set( point( i, j ), t_door_metal_c );
3616 } else {
3617 ter_set( point( i, j ), t_concrete_wall );
3618 }
3619 } else if( ( j == 0 && is_ot_match( "lab", dat.north(), ot_match_type::contains ) ) ||
3620 j == SOUTH_EDGE ) {
3621 if( ter( point( i, j ) ) == t_sewage ) {
3622 ter_set( point( i, j ), t_bars );
3623 } else if( i == SEEX - 1 || i == SEEX ) {
3624 ter_set( point( i, j ), t_door_metal_c );
3625 } else {
3626 ter_set( point( i, j ), t_concrete_wall );
3627 }
3628 }
3629 }
3630 }
3631 } else { // We're below ground, and no sewers
3632 // Set up the boundaries of walls (connect to adjacent lab squares)
3633 tw = is_ot_match( "lab", dat.north(), ot_match_type::contains ) ? 0 : 2;
3634 rw = is_ot_match( "lab", dat.east(), ot_match_type::contains ) ? 1 : 2;
3635 bw = is_ot_match( "lab", dat.south(), ot_match_type::contains ) ? 1 : 2;
3636 lw = is_ot_match( "lab", dat.west(), ot_match_type::contains ) ? 0 : 2;
3637
3638 int boarders = 0;
3639 if( tw == 0 ) {
3640 boarders++;
3641 }
3642 if( rw == 1 ) {
3643 boarders++;
3644 }
3645 if( bw == 1 ) {
3646 boarders++;
3647 }
3648 if( lw == 0 ) {
3649 boarders++;
3650 }
3651
3652 const auto maybe_insert_stairs = [this]( const oter_id & terrain, const ter_id & t_stair_type ) {
3653 if( is_ot_match( "stairs", terrain, ot_match_type::contains ) ) {
3654 const auto predicate = [this]( const tripoint & p ) {
3655 return ter( p ) == t_thconc_floor && furn( p ) == f_null && tr_at( p ).is_null();
3656 };
3657 const auto range = points_in_rectangle( { 0, 0, abs_sub.z }, { SEEX * 2 - 2, SEEY * 2 - 2, abs_sub.z } );
3658
3659 if( const auto p = random_point( range, predicate ) ) {
3660 ter_set( *p, t_stair_type );
3661 }
3662 }
3663 };
3664
3665 //A lab area with only one entrance
3666 if( boarders == 1 ) {
3667 // If you remove the usage of "lab_1side" here, remove it from mapgen_factory::get_usages above as well.
3668 if( oter_mapgen.generate( dat, "lab_1side" ) ) {
3669 if( tw == 2 ) {
3670 rotate( 2 );
3671 }
3672 if( rw == 2 ) {
3673 rotate( 1 );
3674 }
3675 if( lw == 2 ) {
3676 rotate( 3 );
3677 }
3678 } else {
3679 debugmsg( "Error: Tried to generate 1-sided lab but no lab_1side json exists." );
3680 }
3681 maybe_insert_stairs( dat.above(), t_stairs_up );
3682 maybe_insert_stairs( terrain_type, t_stairs_down );
3683 } else {
3684 const int hardcoded_4side_map_weight = 1500; // weight of all hardcoded maps.
3685 // If you remove the usage of "lab_4side" here, remove it from mapgen_factory::get_usages above as well.
3686 if( oter_mapgen.generate( dat, "lab_4side", hardcoded_4side_map_weight ) ) {
3687 // If the map template hasn't handled borders, handle them in code.
3688 // Rotated maps cannot handle borders and have to be caught in code.
3689 // We determine if a border isn't handled by checking the east-facing
3690 // border space where the door normally is -- it should be a wall or door.
3691 tripoint east_border( 23, 11, abs_sub.z );
3692 if( !has_flag_ter( "WALL", east_border ) &&
3693 !has_flag_ter( "DOOR", east_border ) ) {
3694 // TODO: create a ter_reset function that does ter_set,
3695 // furn_set, and i_clear?
3696 ter_id lw_type = tower_lab ? t_reinforced_glass : t_concrete_wall;
3697 ter_id tw_type = tower_lab ? t_reinforced_glass : t_concrete_wall;
3698 ter_id rw_type = tower_lab && rw == 2 ? t_reinforced_glass :
3700 ter_id bw_type = tower_lab && bw == 2 ? t_reinforced_glass :
3702 for( int i = 0; i < SEEX * 2; i++ ) {
3703 ter_set( point( 23, i ), rw_type );
3704 furn_set( point( 23, i ), f_null );
3705 i_clear( tripoint( 23, i, get_abs_sub().z ) );
3706
3707 ter_set( point( i, 23 ), bw_type );
3708 furn_set( point( i, 23 ), f_null );
3709 i_clear( tripoint( i, 23, get_abs_sub().z ) );
3710
3711 if( lw == 2 ) {
3712 ter_set( point( 0, i ), lw_type );
3713 furn_set( point( 0, i ), f_null );
3714 i_clear( tripoint( 0, i, get_abs_sub().z ) );
3715 }
3716 if( tw == 2 ) {
3717 ter_set( point( i, 0 ), tw_type );
3718 furn_set( point( i, 0 ), f_null );
3719 i_clear( tripoint( i, 0, get_abs_sub().z ) );
3720 }
3721 }
3722 if( rw != 2 ) {
3723 ter_set( point( 23, 11 ), t_door_metal_c );
3724 ter_set( point( 23, 12 ), t_door_metal_c );
3725 }
3726 if( bw != 2 ) {
3727 ter_set( point( 11, 23 ), t_door_metal_c );
3728 ter_set( point( 12, 23 ), t_door_metal_c );
3729 }
3730 }
3731
3732 maybe_insert_stairs( dat.above(), t_stairs_up );
3733 maybe_insert_stairs( terrain_type, t_stairs_down );
3734 } else { // then no json maps for lab_4side were found
3735 switch( rng( 1, 3 ) ) {
3736 case 1:
3737 // Cross shaped
3738 for( int i = 0; i < SEEX * 2; i++ ) {
3739 for( int j = 0; j < SEEY * 2; j++ ) {
3740 if( ( i < lw || i > EAST_EDGE - rw ) ||
3741 ( ( j < SEEY - 1 || j > SEEY ) &&
3742 ( i == SEEX - 2 || i == SEEX + 1 ) ) ) {
3743 ter_set( point( i, j ), t_concrete_wall );
3744 } else if( ( j < tw || j > SOUTH_EDGE - bw ) ||
3745 ( ( i < SEEX - 1 || i > SEEX ) &&
3746 ( j == SEEY - 2 || j == SEEY + 1 ) ) ) {
3747 ter_set( point( i, j ), t_concrete_wall );
3748 } else {
3749 ter_set( point( i, j ), t_thconc_floor );
3750 }
3751 }
3752 }
3753 if( is_ot_match( "stairs", dat.above(), ot_match_type::contains ) ) {
3754 ter_set( point( rng( SEEX - 1, SEEX ), rng( SEEY - 1, SEEY ) ),
3755 t_stairs_up );
3756 }
3757 // Top left
3758 if( one_in( 2 ) ) {
3759 ter_set( point( SEEX - 2, int( SEEY / 2 ) ), t_door_glass_frosted_c );
3760 science_room( this, point( lw, tw ), point( SEEX - 3, SEEY - 3 ), dat.zlevel(), 1 );
3761 } else {
3763 science_room( this, point( lw, tw ), point( SEEX - 3, SEEY - 3 ), dat.zlevel(), 2 );
3764 }
3765 // Top right
3766 if( one_in( 2 ) ) {
3767 ter_set( point( SEEX + 1, int( SEEY / 2 ) ), t_door_glass_frosted_c );
3768 science_room( this, point( SEEX + 2, tw ), point( EAST_EDGE - rw, SEEY - 3 ),
3769 dat.zlevel(), 3 );
3770 } else {
3771 ter_set( point( SEEX + int( SEEX / 2 ), SEEY - 2 ), t_door_glass_frosted_c );
3772 science_room( this, point( SEEX + 2, tw ), point( EAST_EDGE - rw, SEEY - 3 ),
3773 dat.zlevel(), 2 );
3774 }
3775 // Bottom left
3776 if( one_in( 2 ) ) {
3778 science_room( this, point( lw, SEEY + 2 ), point( SEEX - 3, SOUTH_EDGE - bw ),
3779 dat.zlevel(), 0 );
3780 } else {
3781 ter_set( point( SEEX - 2, SEEY + int( SEEY / 2 ) ), t_door_glass_frosted_c );
3782 science_room( this, point( lw, SEEY + 2 ), point( SEEX - 3, SOUTH_EDGE - bw ),
3783 dat.zlevel(), 1 );
3784 }
3785 // Bottom right
3786 if( one_in( 2 ) ) {
3787 ter_set( point( SEEX + int( SEEX / 2 ), SEEY + 1 ), t_door_glass_frosted_c );
3788 science_room( this, point( SEEX + 2, SEEY + 2 ), point( EAST_EDGE - rw, SOUTH_EDGE - bw ),
3789 dat.zlevel(), 0 );
3790 } else {
3791 ter_set( point( SEEX + 1, SEEY + int( SEEY / 2 ) ), t_door_glass_frosted_c );
3792 science_room( this, point( SEEX + 2, SEEY + 2 ), point( EAST_EDGE - rw, SOUTH_EDGE - bw ),
3793 dat.zlevel(), 3 );
3794 }
3795 if( rw == 1 ) {
3798 }
3799 if( bw == 1 ) {
3802 }
3803 if( is_ot_match( "stairs", terrain_type, ot_match_type::contains ) ) { // Stairs going down
3804 std::vector<point> stair_points;
3805 if( tw != 0 ) {
3806 stair_points.push_back( point( SEEX - 1, 2 ) );
3807 stair_points.push_back( point( SEEX - 1, 2 ) );
3808 stair_points.push_back( point( SEEX, 2 ) );
3809 stair_points.push_back( point( SEEX, 2 ) );
3810 }
3811 if( rw != 1 ) {
3812 stair_points.push_back( point( SEEX * 2 - 3, SEEY - 1 ) );
3813 stair_points.push_back( point( SEEX * 2 - 3, SEEY - 1 ) );
3814 stair_points.push_back( point( SEEX * 2 - 3, SEEY ) );
3815 stair_points.push_back( point( SEEX * 2 - 3, SEEY ) );
3816 }
3817 if( bw != 1 ) {
3818 stair_points.push_back( point( SEEX - 1, SEEY * 2 - 3 ) );
3819 stair_points.push_back( point( SEEX - 1, SEEY * 2 - 3 ) );
3820 stair_points.push_back( point( SEEX, SEEY * 2 - 3 ) );
3821 stair_points.push_back( point( SEEX, SEEY * 2 - 3 ) );
3822 }
3823 if( lw != 0 ) {
3824 stair_points.push_back( point( 2, SEEY - 1 ) );
3825 stair_points.push_back( point( 2, SEEY - 1 ) );
3826 stair_points.push_back( point( 2, SEEY ) );
3827 stair_points.push_back( point( 2, SEEY ) );
3828 }
3829 stair_points.push_back( point( int( SEEX / 2 ), SEEY ) );
3830 stair_points.push_back( point( int( SEEX / 2 ), SEEY - 1 ) );
3831 stair_points.push_back( point( int( SEEX / 2 ) + SEEX, SEEY ) );
3832 stair_points.push_back( point( int( SEEX / 2 ) + SEEX, SEEY - 1 ) );
3833 stair_points.push_back( point( SEEX, int( SEEY / 2 ) ) );
3834 stair_points.push_back( point( SEEX + 2, int( SEEY / 2 ) ) );
3835 stair_points.push_back( point( SEEX, int( SEEY / 2 ) + SEEY ) );
3836 stair_points.push_back( point( SEEX + 2, int( SEEY / 2 ) + SEEY ) );
3837 const point p = random_entry( stair_points );
3838 ter_set( p, t_stairs_down );
3839 }
3840
3841 break;
3842
3843 case 2:
3844 // tic-tac-toe # layout
3845 for( int i = 0; i < SEEX * 2; i++ ) {
3846 for( int j = 0; j < SEEY * 2; j++ ) {
3847 if( i < lw || i > EAST_EDGE - rw || i == SEEX - 4 ||
3848 i == SEEX + 3 ) {
3849 ter_set( point( i, j ), t_concrete_wall );
3850 } else if( j < tw || j > SOUTH_EDGE - bw || j == SEEY - 4 ||
3851 j == SEEY + 3 ) {
3852 ter_set( point( i, j ), t_concrete_wall );
3853 } else {
3854 ter_set( point( i, j ), t_thconc_floor );
3855 }
3856 }
3857 }
3858 if( is_ot_match( "stairs", dat.above(), ot_match_type::contains ) ) {
3859 ter_set( point( SEEX - 1, SEEY - 1 ), t_stairs_up );
3860 ter_set( point( SEEX, SEEY - 1 ), t_stairs_up );
3861 ter_set( point( SEEX - 1, SEEY ), t_stairs_up );
3863 }
3864 ter_set( point( SEEX - rng( 0, 1 ), SEEY - 4 ), t_door_glass_frosted_c );
3865 ter_set( point( SEEX - rng( 0, 1 ), SEEY + 3 ), t_door_glass_frosted_c );
3866 ter_set( point( SEEX - 4, SEEY + rng( 0, 1 ) ), t_door_glass_frosted_c );
3867 ter_set( point( SEEX + 3, SEEY + rng( 0, 1 ) ), t_door_glass_frosted_c );
3868 ter_set( point( SEEX - 4, int( SEEY / 2 ) ), t_door_glass_frosted_c );
3869 ter_set( point( SEEX + 3, int( SEEY / 2 ) ), t_door_glass_frosted_c );
3872 ter_set( point( SEEX + int( SEEX / 2 ), SEEY - 4 ), t_door_glass_frosted_c );
3873 ter_set( point( SEEX + int( SEEX / 2 ), SEEY + 3 ), t_door_glass_frosted_c );
3874 ter_set( point( SEEX - 4, SEEY + int( SEEY / 2 ) ), t_door_glass_frosted_c );
3875 ter_set( point( SEEX + 3, SEEY + int( SEEY / 2 ) ), t_door_glass_frosted_c );
3876 science_room( this, point( lw, tw ), point( SEEX - 5, SEEY - 5 ), dat.zlevel(),
3877 rng( 1, 2 ) );
3878 science_room( this, point( SEEX - 3, tw ), point( SEEX + 2, SEEY - 5 ), dat.zlevel(), 2 );
3879 science_room( this, point( SEEX + 4, tw ), point( EAST_EDGE - rw, SEEY - 5 ),
3880 dat.zlevel(), rng( 2, 3 ) );
3881 science_room( this, point( lw, SEEY - 3 ), point( SEEX - 5, SEEY + 2 ), dat.zlevel(), 1 );
3882 science_room( this, point( SEEX + 4, SEEY - 3 ), point( EAST_EDGE - rw, SEEY + 2 ),
3883 dat.zlevel(), 3 );
3884 science_room( this, point( lw, SEEY + 4 ), point( SEEX - 5, SOUTH_EDGE - bw ),
3885 dat.zlevel(), rng( 0, 1 ) );
3886 science_room( this, point( SEEX - 3, SEEY + 4 ), point( SEEX + 2, SOUTH_EDGE - bw ),
3887 dat.zlevel(), 0 );
3888 science_room( this, point( SEEX + 4, SEEX + 4 ), point( EAST_EDGE - rw, SOUTH_EDGE - bw ),
3889 dat.zlevel(), 3 * rng( 0, 1 ) );
3890 if( rw == 1 ) {
3893 }
3894 if( bw == 1 ) {
3897 }
3898 if( is_ot_match( "stairs", terrain_type, ot_match_type::contains ) ) {
3899 ter_set( point( SEEX - 3 + 5 * rng( 0, 1 ), SEEY - 3 + 5 * rng( 0, 1 ) ),
3900 t_stairs_down );
3901 }
3902 break;
3903
3904 case 3:
3905 // Big room
3906 for( int i = 0; i < SEEX * 2; i++ ) {
3907 for( int j = 0; j < SEEY * 2; j++ ) {
3908 if( i < lw || i >= EAST_EDGE - rw ) {
3909 ter_set( point( i, j ), t_concrete_wall );
3910 } else if( j < tw || j >= SOUTH_EDGE - bw ) {
3911 ter_set( point( i, j ), t_concrete_wall );
3912 } else {
3913 ter_set( point( i, j ), t_thconc_floor );
3914 }
3915 }
3916 }
3917 science_room( this, point( lw, tw ), point( EAST_EDGE - rw, SOUTH_EDGE - bw ),
3918 dat.zlevel(), rng( 0, 3 ) );
3919
3920 if( rw == 1 ) {
3923 }
3924 if( bw == 1 ) {
3927 }
3928 maybe_insert_stairs( dat.above(), t_stairs_up );
3929 maybe_insert_stairs( terrain_type, t_stairs_down );
3930 break;
3931 }
3932 } // endif use_hardcoded_4side_map
3933 } // end 1 vs 4 sides
3934 } // end aboveground vs belowground
3935
3936 // Ants will totally wreck up the place
3937 if( is_ot_match( "ants", terrain_type, ot_match_type::contains ) ) {
3938 for( int i = 0; i < SEEX * 2; i++ ) {
3939 for( int j = 0; j < SEEY * 2; j++ ) {
3940 // Carve out a diamond area that covers 2 spaces on each edge.
3941 if( i + j > 10 && i + j < 36 && std::abs( i - j ) < 13 ) {
3942 // Doors and walls get sometimes destroyed:
3943 // 100% at the edge, usually in a central cross, occasionally elsewhere.
3944 if( ( has_flag_ter( "DOOR", point( i, j ) ) || has_flag_ter( "WALL", point( i, j ) ) ) ) {
3945 if( ( i == 0 || j == 0 || i == 23 || j == 23 ) ||
3946 ( !one_in( 3 ) && ( i == 11 || i == 12 || j == 11 || j == 12 ) ) ||
3947 one_in( 4 ) ) {
3948 // bash and usually remove the rubble.
3949 make_rubble( { i, j, abs_sub.z } );
3950 ter_set( point( i, j ), t_rock_floor );
3951 if( !one_in( 3 ) ) {
3952 furn_set( point( i, j ), f_null );
3953 }
3954 }
3955 // and then randomly destroy 5% of the remaining nonstairs.
3956 } else if( one_in( 20 ) &&
3957 !has_flag_ter( "GOES_DOWN", p2 ) &&
3958 !has_flag_ter( "GOES_UP", p2 ) ) {
3959 destroy( { i, j, abs_sub.z } );
3960 // bashed squares can create dirt & floors, but we want rock floors.
3961 if( t_dirt == ter( point( i, j ) ) || t_floor == ter( point( i, j ) ) ) {
3962 ter_set( point( i, j ), t_rock_floor );
3963 }
3964 }
3965 }
3966 }
3967 }
3968 }
3969
3970 // Slimes pretty much wreck up the place, too, but only underground
3971 tw = ( dat.north() == "slimepit" ? SEEY : 0 );
3972 rw = ( dat.east() == "slimepit" ? SEEX + 1 : 0 );
3973 bw = ( dat.south() == "slimepit" ? SEEY + 1 : 0 );
3974 lw = ( dat.west() == "slimepit" ? SEEX : 0 );
3975 if( tw != 0 || rw != 0 || bw != 0 || lw != 0 ) {
3976 for( int i = 0; i < SEEX * 2; i++ ) {
3977 for( int j = 0; j < SEEY * 2; j++ ) {
3978 if( ( ( j <= tw || i >= rw ) && i >= j && ( EAST_EDGE - i ) <= j ) ||
3979 ( ( j >= bw || i <= lw ) && i <= j && ( SOUTH_EDGE - j ) <= i ) ) {
3980 if( one_in( 5 ) ) {
3981 make_rubble( tripoint( i, j, abs_sub.z ), f_rubble_rock, true,
3982 t_slime );
3983 } else if( !one_in( 5 ) ) {
3984 ter_set( point( i, j ), t_slime );
3985 }
3986 }
3987 }
3988 }
3989 }
3990
3991 int light_odds = 0;
3992 // central labs are always fully lit, other labs have half chance of some lights.
3993 if( central_lab ) {
3994 light_odds = 1;
3995 } else if( one_in( 2 ) ) {
3996 // Create a spread of densities, from all possible lights on, to 1/3, ...
3997 // to ~1 per segment.
3998 light_odds = std::pow( rng( 1, 12 ), 1.6 );
3999 }
4000 if( light_odds > 0 ) {
4001 for( int i = 0; i < SEEX * 2; i++ ) {
4002 for( int j = 0; j < SEEY * 2; j++ ) {
4003 if( !( ( i * j ) % 2 || ( i + j ) % 4 ) && one_in( light_odds ) ) {
4004 if( t_thconc_floor == ter( point( i, j ) ) || t_strconc_floor == ter( point( i, j ) ) ) {
4006 }
4007 }
4008 }
4009 }
4010 }
4011
4012 if( tower_lab ) {
4014 }
4015
4016 // Lab special effects.
4017 if( one_in( 10 ) ) {
4018 switch( rng( 1, 7 ) ) {
4019 // full flooding/sewage
4020 case 1: {
4021 if( is_ot_match( "stairs", terrain_type, ot_match_type::contains ) ||
4022 is_ot_match( "ice", terrain_type, ot_match_type::contains ) ) {
4023 // don't flood if stairs because the floor below will not be flooded.
4024 // don't flood if ice lab because there's no mechanic for freezing
4025 // liquid floors.
4026 break;
4027 }
4028 auto fluid_type = one_in( 3 ) ? t_sewage : t_water_sh;
4029 for( int i = 0; i < EAST_EDGE; i++ ) {
4030 for( int j = 0; j < SOUTH_EDGE; j++ ) {
4031 // We spare some terrain to make it look better visually.
4032 if( !one_in( 10 ) && ( t_thconc_floor == ter( point( i, j ) ) ||
4033 t_strconc_floor == ter( point( i, j ) ) ||
4034 t_thconc_floor_olight == ter( point( i, j ) ) ) ) {
4035 ter_set( point( i, j ), fluid_type );
4036 } else if( has_flag_ter( "DOOR", point( i, j ) ) && !one_in( 3 ) ) {
4037 // We want the actual debris, but not the rubble marker or dirt.
4038 make_rubble( { i, j, abs_sub.z } );
4039 ter_set( point( i, j ), fluid_type );
4040 furn_set( point( i, j ), f_null );
4041 }
4042 }
4043 }
4044 break;
4045 }
4046 // minor flooding/sewage
4047 case 2: {
4048 if( is_ot_match( "stairs", terrain_type, ot_match_type::contains ) ||
4049 is_ot_match( "ice", terrain_type, ot_match_type::contains ) ) {
4050 // don't flood if stairs because the floor below will not be flooded.
4051 // don't flood if ice lab because there's no mechanic for freezing
4052 // liquid floors.
4053 break;
4054 }
4055 auto fluid_type = one_in( 3 ) ? t_sewage : t_water_sh;
4056 for( int i = 0; i < 2; ++i ) {
4057 draw_rough_circle( [this, fluid_type]( const point & p ) {
4058 if( t_thconc_floor == ter( p ) || t_strconc_floor == ter( p ) ||
4059 t_thconc_floor_olight == ter( p ) ) {
4060 ter_set( p, fluid_type );
4061 } else if( has_flag_ter( "DOOR", p ) ) {
4062 // We want the actual debris, but not the rubble marker or dirt.
4063 make_rubble( { p, abs_sub.z } );
4064 ter_set( p, fluid_type );
4065 furn_set( p, f_null );
4066 }
4067 }, point( rng( 1, SEEX * 2 - 2 ), rng( 1, SEEY * 2 - 2 ) ), rng( 3, 6 ) );
4068 }
4069 break;
4070 }
4071 // toxic gas leaks and smoke-filled rooms.
4072 case 3:
4073 case 4: {
4074 bool is_toxic = one_in( 3 );
4075 for( int i = 0; i < SEEX * 2; i++ ) {
4076 for( int j = 0; j < SEEY * 2; j++ ) {
4077 if( one_in( 200 ) && ( t_thconc_floor == ter( point( i, j ) ) ||
4078 t_strconc_floor == ter( point( i, j ) ) ) ) {
4079 if( is_toxic ) {
4080 add_field( {i, j, abs_sub.z}, fd_gas_vent, 1 );
4081 } else {
4082 add_field( {i, j, abs_sub.z}, fd_smoke_vent, 2 );
4083 }
4084 }
4085 }
4086 }
4087 break;
4088 }
4089 // portal with an artifact effect.
4090 case 5: {
4091 tripoint center( rng( 6, SEEX * 2 - 7 ), rng( 6, SEEY * 2 - 7 ), abs_sub.z );
4092 std::vector<artifact_natural_property> valid_props = {
4099 };
4100 draw_rough_circle( [this]( const point & p ) {
4101 if( has_flag_ter( "GOES_DOWN", p ) ||
4102 has_flag_ter( "GOES_UP", p ) ||
4103 has_flag_ter( "CONSOLE", p ) ) {
4104 return; // spare stairs and consoles.
4105 }
4106 make_rubble( {p, abs_sub.z } );
4107 ter_set( p, t_thconc_floor );
4108 }, center.xy(), 4 );
4109 furn_set( center.xy(), f_null );
4111 create_anomaly( center, random_entry( valid_props ), false );
4112 break;
4113 }
4114 // radioactive accident.
4115 case 6: {
4116 tripoint center( rng( 6, SEEX * 2 - 7 ), rng( 6, SEEY * 2 - 7 ), abs_sub.z );
4117 if( has_flag_ter( "WALL", center.xy() ) ) {
4118 // just skip it, we don't want to risk embedding radiation out of sight.
4119 break;
4120 }
4121 draw_rough_circle( [this]( const point & p ) {
4122 set_radiation( p, 10 );
4123 }, center.xy(), rng( 7, 12 ) );
4124 draw_circle( [this]( const point & p ) {
4125 set_radiation( p, 20 );
4126 }, center.xy(), rng( 5, 8 ) );
4127 draw_circle( [this]( const point & p ) {
4128 set_radiation( p, 30 );
4129 }, center.xy(), rng( 2, 4 ) );
4130 draw_circle( [this]( const point & p ) {
4131 set_radiation( p, 50 );
4132 }, center.xy(), 1 );
4133 draw_circle( [this]( const point & p ) {
4134 if( has_flag_ter( "GOES_DOWN", p ) ||
4135 has_flag_ter( "GOES_UP", p ) ||
4136 has_flag_ter( "CONSOLE", p ) ) {
4137 return; // spare stairs and consoles.
4138 }
4139 make_rubble( {p, abs_sub.z } );
4140 ter_set( p, t_thconc_floor );
4141 }, center.xy(), 1 );
4142
4144 center.xy() + point_west, 1, true );
4146 center.xy() + point_west, 1, true );
4147
4148 // damaged mininuke/plut thrown past edge of rubble so the player can see it.
4149 int marker_x = center.x - 2 + 4 * rng( 0, 1 );
4150 int marker_y = center.y + rng( -2, 2 );
4151 if( one_in( 4 ) ) {
4152 spawn_item(
4153 point( marker_x, marker_y ), "mininuke", 1, 1, calendar::start_of_cataclysm, rng( 2, 4 )
4154 );
4155 } else {
4156 item newliquid( "plut_slurry_dense", calendar::start_of_cataclysm );
4157 newliquid.charges = 1;
4158 add_item_or_charges( tripoint( marker_x, marker_y, get_abs_sub().z ),
4159 newliquid );
4160 }
4161 break;
4162 }
4163 // portal with fungal invasion
4164 case 7: {
4165 for( int i = 0; i < EAST_EDGE; i++ ) {
4166 for( int j = 0; j < SOUTH_EDGE; j++ ) {
4167 // Create a mostly spread fungal area throughout entire lab.
4168 if( !one_in( 5 ) && ( has_flag( "FLAT", point( i, j ) ) ) ) {
4169 ter_set( point( i, j ), t_fungus_floor_in );
4170 if( has_flag_furn( "ORGANIC", point( i, j ) ) ) {
4171 furn_set( point( i, j ), f_fungal_clump );
4172 }
4173 } else if( has_flag_ter( "DOOR", point( i, j ) ) && !one_in( 5 ) ) {
4174 ter_set( point( i, j ), t_fungus_floor_in );
4175 } else if( has_flag_ter( "WALL", point( i, j ) ) && one_in( 3 ) ) {
4176 ter_set( point( i, j ), t_fungus_wall );
4177 }
4178 }
4179 }
4180 tripoint center( rng( 6, SEEX * 2 - 7 ), rng( 6, SEEY * 2 - 7 ), abs_sub.z );
4181
4182 // Make a portal surrounded by more dense fungal stuff and a fungaloid.
4183 draw_rough_circle( [this]( const point & p ) {
4184 if( has_flag_ter( "GOES_DOWN", p ) ||
4185 has_flag_ter( "GOES_UP", p ) ||
4186 has_flag_ter( "CONSOLE", p ) ) {
4187 return; // spare stairs and consoles.
4188 }
4189 if( has_flag_ter( "WALL", p ) ) {
4190 ter_set( p, t_fungus_wall );
4191 } else {
4193 if( one_in( 3 ) ) {
4195 } else if( one_in( 10 ) ) {
4196 ter_set( p, t_marloss );
4197 }
4198 }
4199 }, center.xy(), 3 );
4201 furn_set( center.xy(), f_null );
4203 place_spawns( GROUP_FUNGI_FUNGALOID, 1, center.xy() + point( -2, -2 ),
4204 center.xy() + point( 2, 2 ), 1, true );
4205
4206 break;
4207 }
4208 }
4209 }
4210 } else if( terrain_type == "lab_finale" || terrain_type == "ice_lab_finale" ||
4211 terrain_type == "central_lab_finale" || terrain_type == "tower_lab_finale" ) {
4212
4213 ice_lab = is_ot_match( "ice_lab", terrain_type, ot_match_type::prefix );
4214 central_lab = is_ot_match( "central_lab", terrain_type, ot_match_type::prefix );
4215 tower_lab = is_ot_match( "tower_lab", terrain_type, ot_match_type::prefix );
4216
4217 if( ice_lab ) {
4218 int temperature = -20 + 30 * dat.zlevel();
4220 set_temperature( p2 + point( SEEX, 0 ), temperature );
4221 set_temperature( p2 + point( 0, SEEY ), temperature );
4223 }
4224
4225 tw = is_ot_match( "lab", dat.north(), ot_match_type::contains ) ? 0 : 2;
4226 rw = is_ot_match( "lab", dat.east(), ot_match_type::contains ) ? 1 : 2;
4227 bw = is_ot_match( "lab", dat.south(), ot_match_type::contains ) ? 1 : 2;
4228 lw = is_ot_match( "lab", dat.west(), ot_match_type::contains ) ? 0 : 2;
4229
4230 const int hardcoded_finale_map_weight = 500; // weight of all hardcoded maps.
4231 // If you remove the usage of "lab_finale_1level" here, remove it from mapgen_factory::get_usages above as well.
4232 if( oter_mapgen.generate( dat, "lab_finale_1level", hardcoded_finale_map_weight ) ) {
4233 // If the map template hasn't handled borders, handle them in code.
4234 // Rotated maps cannot handle borders and have to be caught in code.
4235 // We determine if a border isn't handled by checking the east-facing
4236 // border space where the door normally is -- it should be a wall or door.
4237 tripoint east_border( 23, 11, abs_sub.z );
4238 if( !has_flag_ter( "WALL", east_border ) && !has_flag_ter( "DOOR", east_border ) ) {
4239 // TODO: create a ter_reset function that does ter_set, furn_set, and i_clear?
4240 ter_id lw_type = tower_lab ? t_reinforced_glass : t_concrete_wall;
4241 ter_id tw_type = tower_lab ? t_reinforced_glass : t_concrete_wall;
4242 ter_id rw_type = tower_lab && rw == 2 ? t_reinforced_glass : t_concrete_wall;
4243 ter_id bw_type = tower_lab && bw == 2 ? t_reinforced_glass : t_concrete_wall;
4244 for( int i = 0; i < SEEX * 2; i++ ) {
4245 ter_set( point( 23, i ), rw_type );
4246 furn_set( point( 23, i ), f_null );
4247 i_clear( tripoint( 23, i, get_abs_sub().z ) );
4248
4249 ter_set( point( i, 23 ), bw_type );
4250 furn_set( point( i, 23 ), f_null );
4251 i_clear( tripoint( i, 23, get_abs_sub().z ) );
4252
4253 if( lw == 2 ) {
4254 ter_set( point( 0, i ), lw_type );
4255 furn_set( point( 0, i ), f_null );
4256 i_clear( tripoint( 0, i, get_abs_sub().z ) );
4257 }
4258 if( tw == 2 ) {
4259 ter_set( point( i, 0 ), tw_type );
4260 furn_set( point( i, 0 ), f_null );
4261 i_clear( tripoint( i, 0, get_abs_sub().z ) );
4262 }
4263 }
4264 if( rw != 2 ) {
4265 ter_set( point( 23, 11 ), t_door_metal_c );
4266 ter_set( point( 23, 12 ), t_door_metal_c );
4267 }
4268 if( bw != 2 ) {
4269 ter_set( point( 11, 23 ), t_door_metal_c );
4270 ter_set( point( 12, 23 ), t_door_metal_c );
4271 }
4272 }
4273 } else { // then no json maps for lab_finale_1level were found
4274 // Start by setting up a large, empty room.
4275 for( int i = 0; i < SEEX * 2; i++ ) {
4276 for( int j = 0; j < SEEY * 2; j++ ) {
4277 if( i < lw || i > EAST_EDGE - rw ) {
4278 ter_set( point( i, j ), t_concrete_wall );
4279 } else if( j < tw || j > SOUTH_EDGE - bw ) {
4280 ter_set( point( i, j ), t_concrete_wall );
4281 } else {
4282 ter_set( point( i, j ), t_thconc_floor );
4283 }
4284 }
4285 }
4286 if( rw == 1 ) {
4289 }
4290 if( bw == 1 ) {
4293 }
4294
4295 int loot_variant; //only used for weapons testing variant.
4296 computer *tmpcomp = nullptr;
4297 switch( rng( 1, 5 ) ) {
4298 // Weapons testing - twice as common because it has 4 variants.
4299 case 1:
4300 case 2:
4301 loot_variant = rng( 1, 100 ); //The variants have a 67/22/7/4 split.
4302 place_spawns( GROUP_ROBOT_SECUBOT, 1, point( 6, 6 ), point( 6, 6 ), 1, true );
4303 place_spawns( GROUP_ROBOT_SECUBOT, 1, point( SEEX * 2 - 7, 6 ),
4304 point( SEEX * 2 - 7, 6 ), 1, true );
4305 place_spawns( GROUP_ROBOT_SECUBOT, 1, point( 6, SEEY * 2 - 7 ),
4306 point( 6, SEEY * 2 - 7 ), 1, true );
4307 place_spawns( GROUP_ROBOT_SECUBOT, 1, point( SEEX * 2 - 7, SEEY * 2 - 7 ),
4308 point( SEEX * 2 - 7, SEEY * 2 - 7 ), 1, true );
4309 spawn_item( point( SEEX - 4, SEEY - 2 ), "id_science" );
4310 if( loot_variant <= 96 ) {
4311 mtrap_set( this, point( SEEX - 3, SEEY - 3 ), tr_dissector );
4312 mtrap_set( this, point( SEEX + 2, SEEY - 3 ), tr_dissector );
4313 mtrap_set( this, point( SEEX - 3, SEEY + 2 ), tr_dissector );
4314 mtrap_set( this, point( SEEX + 2, SEEY + 2 ), tr_dissector );
4315 line( this, t_reinforced_glass, point( SEEX + 1, SEEY + 1 ), point( SEEX - 2, SEEY + 1 ) );
4316 line( this, t_reinforced_glass, point( SEEX - 2, SEEY ), point( SEEX - 2, SEEY - 2 ) );
4317 line( this, t_reinforced_glass, point( SEEX - 1, SEEY - 2 ), point( SEEX + 1, SEEY - 2 ) );
4318 ter_set( point( SEEX + 1, SEEY - 1 ), t_reinforced_glass );
4320 furn_set( point( SEEX - 1, SEEY - 1 ), f_table );
4321 furn_set( point( SEEX, SEEY - 1 ), f_table );
4322 furn_set( point( SEEX - 1, SEEY ), f_table );
4323 furn_set( point( SEEX, SEEY ), f_table );
4324 if( loot_variant <= 67 ) {
4325 spawn_item( point( SEEX, SEEY - 1 ), "UPS_off" );
4326 spawn_item( point( SEEX, SEEY - 1 ), "heavy_battery_cell" );
4327 spawn_item( point( SEEX - 1, SEEY ), "v29" );
4328 spawn_item( point( SEEX - 1, SEEY ), "laser_rifle", dice( 1, 0 ) );
4329 spawn_item( point( SEEX, SEEY ), "plasma_gun" );
4330 spawn_item( point( SEEX, SEEY ), "plasma" );
4331 spawn_item( point( SEEX - 1, SEEY ), "recipe_atomic_battery" );
4332 spawn_item( point( SEEX + 1, SEEY ), "plut_cell", rng( 8, 20 ) );
4333 } else if( loot_variant < 89 ) {
4334 spawn_item( point( SEEX - 1, SEEY - 1 ), "mininuke", dice( 3, 6 ) );
4335 spawn_item( point( SEEX, SEEY - 1 ), "mininuke", dice( 3, 6 ) );
4336 spawn_item( point( SEEX - 1, SEEY ), "mininuke", dice( 3, 6 ) );
4337 spawn_item( point( SEEX, SEEY ), "mininuke", dice( 3, 6 ) );
4338 spawn_item( point( SEEX, SEEY ), "recipe_atomic_battery" );
4339 spawn_item( point( SEEX + 1, SEEY ), "plut_cell", rng( 8, 20 ) );
4340 } else { // loot_variant between 90 and 96.
4341 spawn_item( point( SEEX - 1, SEEY - 1 ), "rm13_armor" );
4342 spawn_item( point( SEEX, SEEY - 1 ), "plut_cell" );
4343 spawn_item( point( SEEX - 1, SEEY ), "plut_cell" );
4344 spawn_item( point( SEEX, SEEY ), "recipe_caseless" );
4345 }
4346 } else { // 4% of the lab ends will be this weapons testing end.
4347 mtrap_set( this, point( SEEX - 4, SEEY - 3 ), tr_dissector );
4348 mtrap_set( this, point( SEEX + 3, SEEY - 3 ), tr_dissector );
4349 mtrap_set( this, point( SEEX - 4, SEEY + 2 ), tr_dissector );
4350 mtrap_set( this, point( SEEX + 3, SEEY + 2 ), tr_dissector );
4351
4352 furn_set( point( SEEX - 2, SEEY - 1 ), f_rack );
4353 furn_set( point( SEEX - 1, SEEY - 1 ), f_rack );
4354 furn_set( point( SEEX, SEEY - 1 ), f_rack );
4355 furn_set( point( SEEX + 1, SEEY - 1 ), f_rack );
4356 furn_set( point( SEEX - 2, SEEY ), f_rack );
4357 furn_set( point( SEEX - 1, SEEY ), f_rack );
4358 furn_set( point( SEEX, SEEY ), f_rack );
4359 furn_set( point( SEEX + 1, SEEY ), f_rack );
4360 line( this, t_reinforced_door_glass_c, point( SEEX - 2, SEEY - 2 ),
4361 point( SEEX + 1, SEEY - 2 ) );
4362 line( this, t_reinforced_door_glass_c, point( SEEX - 2, SEEY + 1 ),
4363 point( SEEX + 1, SEEY + 1 ) );
4364 line( this, t_reinforced_glass, point( SEEX - 3, SEEY - 2 ), point( SEEX - 3, SEEY + 1 ) );
4365 line( this, t_reinforced_glass, point( SEEX + 2, SEEY - 2 ), point( SEEX + 2, SEEY + 1 ) );
4366 place_items( item_group_id( "ammo_rare" ), 96, point( SEEX - 2, SEEY - 1 ),
4367 point( SEEX + 1, SEEY - 1 ), false, calendar::start_of_cataclysm );
4368 place_items( item_group_id( "guns_rare" ), 96, point( SEEX - 2, SEEY ), point( SEEX + 1, SEEY ),
4369 false,
4371 spawn_item( point( SEEX + 1, SEEY ), "plut_cell", rng( 1, 10 ) );
4372 }
4373 break;
4374 // Netherworld access
4375 case 3: {
4376 bool monsters_end = false;
4377 if( !one_in( 4 ) ) { // Trapped netherworld monsters
4378 monsters_end = true;
4379 tw = rng( SEEY + 3, SEEY + 5 );
4380 bw = tw + 4;
4381 lw = rng( SEEX - 6, SEEX - 2 );
4382 rw = lw + 6;
4383 for( int i = lw; i <= rw; i++ ) {
4384 for( int j = tw; j <= bw; j++ ) {
4385 if( j == tw || j == bw ) {
4386 if( ( i - lw ) % 2 == 0 ) {
4387 ter_set( point( i, j ), t_concrete_wall );
4388 } else {
4389 ter_set( point( i, j ), t_reinforced_glass );
4390 }
4391 } else if( ( i - lw ) % 2 == 0 ) {
4392 ter_set( point( i, j ), t_concrete_wall );
4393 } else if( j == tw + 2 ) {
4394 ter_set( point( i, j ), t_concrete_wall );
4395 } else { // Empty space holds monsters!
4396 place_spawns( GROUP_NETHER, 1, point( i, j ), point( i, j ), 1, true );
4397 }
4398 }
4399 }
4400 }
4401
4402 spawn_item( point( SEEX - 1, 8 ), "id_science" );
4403 tmpcomp = add_computer( tripoint( SEEX, 8, abs_sub.z ),
4404 _( "Sub-prime contact console" ), 7 );
4405 if( monsters_end ) { //only add these options when there are monsters.
4406 tmpcomp->add_option( _( "Terminate Specimens" ), COMPACT_TERMINATE, 2 );
4407 tmpcomp->add_option( _( "Release Specimens" ), COMPACT_RELEASE, 3 );
4408 }
4409 tmpcomp->add_option( _( "Toggle Portal" ), COMPACT_PORTAL, 8 );
4410 tmpcomp->add_option( _( "Activate Resonance Cascade" ), COMPACT_CASCADE, 10 );
4411 tmpcomp->add_failure( COMPFAIL_MANHACKS );
4412 tmpcomp->add_failure( COMPFAIL_SECUBOTS );
4413 tmpcomp->set_access_denied_msg(
4414 _( "ERROR! Access denied! Unauthorized access will be met with lethal force!" ) );
4415 ter_set( point( SEEX - 2, 4 ), t_radio_tower );
4416 ter_set( point( SEEX + 1, 4 ), t_radio_tower );
4417 ter_set( point( SEEX - 2, 7 ), t_radio_tower );
4418 ter_set( point( SEEX + 1, 7 ), t_radio_tower );
4419 }
4420 break;
4421
4422 // Bionics
4423 case 4: {
4424 place_spawns( GROUP_ROBOT_SECUBOT, 1, point( 6, 6 ), point( 6, 6 ), 1, true );
4425 place_spawns( GROUP_ROBOT_SECUBOT, 1, point( SEEX * 2 - 7, 6 ),
4426 point( SEEX * 2 - 7, 6 ), 1, true );
4427 place_spawns( GROUP_ROBOT_SECUBOT, 1, point( 6, SEEY * 2 - 7 ),
4428 point( 6, SEEY * 2 - 7 ), 1, true );
4429 place_spawns( GROUP_ROBOT_SECUBOT, 1, point( SEEX * 2 - 7, SEEY * 2 - 7 ),
4430 point( SEEX * 2 - 7, SEEY * 2 - 7 ), 1, true );
4431 mtrap_set( this, point( SEEX - 2, SEEY - 2 ), tr_dissector );
4432 mtrap_set( this, point( SEEX + 1, SEEY - 2 ), tr_dissector );
4433 mtrap_set( this, point( SEEX - 2, SEEY + 1 ), tr_dissector );
4434 mtrap_set( this, point( SEEX + 1, SEEY + 1 ), tr_dissector );
4435 square_furn( this, f_counter, point( SEEX - 1, SEEY - 1 ), point( SEEX, SEEY ) );
4436 int item_count = 0;
4437 while( item_count < 5 ) {
4438 item_count += place_items( item_group_id( "bionics" ), 75, point( SEEX - 1, SEEY - 1 ),
4439 point( SEEX, SEEY ), false, calendar::start_of_cataclysm ).size();
4440 }
4441 line( this, t_reinforced_glass, point( SEEX - 2, SEEY - 2 ), point( SEEX + 1, SEEY - 2 ) );
4442 line( this, t_reinforced_glass, point( SEEX - 2, SEEY + 1 ), point( SEEX + 1, SEEY + 1 ) );
4443 line( this, t_reinforced_glass, point( SEEX - 2, SEEY - 1 ), point( SEEX - 2, SEEY ) );
4444 line( this, t_reinforced_glass, point( SEEX + 1, SEEY - 1 ), point( SEEX + 1, SEEY ) );
4445 spawn_item( point( SEEX - 4, SEEY - 3 ), "id_science" );
4446 ter_set( point( SEEX - 3, SEEY - 3 ), t_console );
4447 tmpcomp = add_computer( tripoint( SEEX - 3, SEEY - 3, abs_sub.z ),
4448 _( "Bionic access" ), 3 );
4449 tmpcomp->add_option( _( "Manifest" ), COMPACT_LIST_BIONICS, 0 );
4450 tmpcomp->add_option( _( "Open Chambers" ), COMPACT_RELEASE, 5 );
4451 tmpcomp->add_failure( COMPFAIL_MANHACKS );
4452 tmpcomp->add_failure( COMPFAIL_SECUBOTS );
4453 tmpcomp->set_access_denied_msg(
4454 _( "ERROR! Access denied! Unauthorized access will be met with lethal force!" ) );
4455 }
4456 break;
4457
4458 // CVD Forge
4459 case 5:
4460 place_spawns( GROUP_ROBOT_SECUBOT, 1, point( 6, 6 ), point( 6, 6 ), 1, true );
4461 place_spawns( GROUP_ROBOT_SECUBOT, 1, point( SEEX * 2 - 7, 6 ),
4462 point( SEEX * 2 - 7, 6 ), 1, true );
4463 place_spawns( GROUP_ROBOT_SECUBOT, 1, point( 6, SEEY * 2 - 7 ),
4464 point( 6, SEEY * 2 - 7 ), 1, true );
4465 place_spawns( GROUP_ROBOT_SECUBOT, 1, point( SEEX * 2 - 7, SEEY * 2 - 7 ),
4466 point( SEEX * 2 - 7, SEEY * 2 - 7 ), 1, true );
4467 line( this, t_cvdbody, point( SEEX - 2, SEEY - 2 ), point( SEEX - 2, SEEY + 1 ) );
4468 line( this, t_cvdbody, point( SEEX - 1, SEEY - 2 ), point( SEEX - 1, SEEY + 1 ) );
4469 line( this, t_cvdbody, point( SEEX, SEEY - 1 ), point( SEEX, SEEY + 1 ) );
4470 line( this, t_cvdbody, point( SEEX + 1, SEEY - 2 ), point( SEEX + 1, SEEY + 1 ) );
4471 ter_set( point( SEEX, SEEY - 2 ), t_cvdmachine );
4472 spawn_item( point( SEEX, SEEY - 3 ), "id_science" );
4473 break;
4474 }
4475 } // end use_hardcoded_lab_finale
4476
4477 // Handle stairs in the unlikely case they are needed.
4478
4479 const auto maybe_insert_stairs = [this]( const oter_id & terrain, const ter_id & t_stair_type ) {
4480 if( is_ot_match( "stairs", terrain, ot_match_type::contains ) ) {
4481 const auto predicate = [this]( const tripoint & p ) {
4482 return ter( p ) == t_thconc_floor && furn( p ) == f_null &&
4483 tr_at( p ).is_null();
4484 };
4485 const auto range = points_in_rectangle( { 0, 0, abs_sub.z },
4486 { SEEX * 2 - 2, SEEY * 2 - 2, abs_sub.z } );
4487 if( const auto p = random_point( range, predicate ) ) {
4488 ter_set( *p, t_stair_type );
4489 }
4490 }
4491 };
4492 maybe_insert_stairs( dat.above(), t_stairs_up );
4493 maybe_insert_stairs( terrain_type, t_stairs_down );
4494
4495 int light_odds = 0;
4496 // central labs are always fully lit, other labs have half chance of some lights.
4497 if( central_lab ) {
4498 light_odds = 1;
4499 } else if( one_in( 2 ) ) {
4500 light_odds = std::pow( rng( 1, 12 ), 1.6 );
4501 }
4502 if( light_odds > 0 ) {
4503 for( int i = 0; i < SEEX * 2; i++ ) {
4504 for( int j = 0; j < SEEY * 2; j++ ) {
4505 if( !( ( i * j ) % 2 || ( i + j ) % 4 ) && one_in( light_odds ) ) {
4506 if( t_thconc_floor == ter( point( i, j ) ) || t_strconc_floor == ter( point( i, j ) ) ) {
4508 }
4509 }
4510 }
4511 }
4512 }
4513 }
4514}
void set_access_denied_msg(const std::string &new_msg)
Definition: computer.cpp:97
void add_failure(const computer_failure &failure)
Definition: computer.cpp:87
void add_option(const computer_option &opt)
Definition: computer.cpp:76
void set_temperature(const tripoint &p, int temperature)
Definition: map.cpp:4059
computer * add_computer(const tripoint &p, const std::string &name, int security)
Definition: mapgen.cpp:5783
void i_clear(const tripoint &p)
Definition: map.cpp:4107
std::vector< item * > place_items(const item_group_id &loc, int chance, const tripoint &p1, const tripoint &p2, bool ongrass, const time_point &turn, int magazine=0, int ammo=0)
Place items from item group in the rectangle f - t.
Definition: mapgen.cpp:5513
void trap_set(const tripoint &p, const trap_id &type)
Definition: map.cpp:5167
bool generate(mapgendata &dat, const std::string &key, const int hardcoded_weight=0) const
Definition: mapgen.cpp:340
int zlevel() const
Definition: mapgendata.h:99
@ COMPACT_RELEASE
Definition: computer.h:42
@ COMPACT_TERMINATE
Definition: computer.h:59
@ COMPACT_PORTAL
Definition: computer.h:40
@ COMPACT_CASCADE
Definition: computer.h:19
@ COMPACT_LIST_BIONICS
Definition: computer.h:32
@ COMPFAIL_SECUBOTS
Definition: computer.h:77
@ COMPFAIL_MANHACKS
Definition: computer.h:74
void draw_rough_circle(std::function< void(const point &)>set, const point &p, int rad)
@ prefix
Definition: enums.h:79
@ contains
Definition: enums.h:83
field_type_id fd_gas_vent
Definition: field_type.cpp:350
field_type_id fd_smoke_vent
Definition: field_type.cpp:385
ter_id t_door_glass_frosted_c
Definition: mapdata.cpp:664
ter_id t_cvdmachine
Definition: mapdata.cpp:712
ter_id t_slime
Definition: mapdata.cpp:637
ter_id t_strconc_floor
Definition: mapdata.cpp:631
furn_id f_table
Definition: mapdata.cpp:1104
furn_id f_fungal_clump
Definition: mapdata.cpp:1116
ter_id t_cvdbody
Definition: mapdata.cpp:712
ter_id t_radio_tower
Definition: mapdata.cpp:703
ter_id t_fungus_floor_in
Definition: mapdata.cpp:690
furn_id f_counter
Definition: mapdata.cpp:1105
furn_id f_rack
Definition: mapdata.cpp:1107
ter_id t_fungus_wall
Definition: mapdata.cpp:690
ter_id t_reinforced_glass
Definition: mapdata.cpp:650
ter_id t_concrete_wall
Definition: mapdata.cpp:646
ter_id t_floor
Definition: mapdata.cpp:632
ter_id t_thconc_floor_olight
Definition: mapdata.cpp:631
ter_id t_bars
Definition: mapdata.cpp:653
ter_id t_thconc_floor
Definition: mapdata.cpp:631
furn_id f_rubble_rock
Definition: mapdata.cpp:1097
ter_id t_stairs_up
Definition: mapdata.cpp:718
ter_id t_stairs_down
Definition: mapdata.cpp:718
ter_id t_marloss
Definition: mapdata.cpp:690
ter_id t_door_metal_locked
Definition: mapdata.cpp:662
ter_id t_card_science
Definition: mapdata.cpp:722
ter_id t_reinforced_door_glass_c
Definition: mapdata.cpp:652
furn_id f_flower_fungal
Definition: mapdata.cpp:1116
void square_furn(map *m, const furn_id &type, const point &p1, const point &p2)
Definition: mapgen.cpp:6475
static const mongroup_id GROUP_ROBOT_SECUBOT("GROUP_ROBOT_SECUBOT")
static const mongroup_id GROUP_HAZMATBOT("GROUP_HAZMATBOT")
static const mongroup_id GROUP_NETHER("GROUP_NETHER")
static const mongroup_id GROUP_TURRET("GROUP_TURRET")
void line(map *m, const ter_id &type, const point &p1, const point &p2)
Definition: mapgen.cpp:6455
static void science_room(map *m, const point &p1, const point &p2, int z, int rotate)
Definition: mapgen.cpp:5949
const int SOUTH_EDGE
Definition: mapgen.cpp:2924
const int EAST_EDGE
Definition: mapgen.cpp:2925
static mapgen_factory oter_mapgen
Definition: mapgen.cpp:349
static const mongroup_id GROUP_FUNGI_FUNGALOID("GROUP_FUNGI_FUNGALOID")
static const mongroup_id GROUP_LAB("GROUP_LAB")
static const trap_str_id tr_portal("tr_portal")
static const trap_str_id tr_dissector("tr_dissector")
const time_point & start_of_cataclysm
Definition: calendar.cpp:33
quantity< int, temperature_in_millidegree_celsius_tag > temperature
std::pair< item, int > item_count
Definition: pickup.cpp:63
int dice(int number, int sides)
Definition: rng.cpp:85
V random_entry(const C &container, D default_value)
Returns a random entry in the container.
Definition: rng.h:88

References _, mapgendata::above(), abs_sub, add_computer(), computer::add_failure(), add_field(), add_item_or_charges(), computer::add_option(), ARTPROP_BREATHING, ARTPROP_CRACKLING, ARTPROP_GLOWING, ARTPROP_SCALED, ARTPROP_WARM, ARTPROP_WHISPERING, center, item::charges, COMPACT_CASCADE, COMPACT_LIST_BIONICS, COMPACT_PORTAL, COMPACT_RELEASE, COMPACT_TERMINATE, COMPFAIL_MANHACKS, COMPFAIL_SECUBOTS, connects_to(), contains, create_anomaly(), debugmsg, destroy(), dice(), draw_circle(), draw_rough_circle(), mapgendata::east(), EAST_EDGE, f_counter, f_flower_fungal, f_fungal_clump, f_null, f_rack, f_rubble_rock, f_table, fd_gas_vent, fd_smoke_vent, furn(), furn_set(), mapgen_factory::generate(), get_abs_sub(), GROUP_FUNGI_FUNGALOID, GROUP_HAZMATBOT, GROUP_LAB, GROUP_NETHER, GROUP_ROBOT_SECUBOT, GROUP_TURRET, has_flag(), has_flag_furn(), has_flag_ter(), i_clear(), trap::is_null(), is_ot_match(), line(), make_rubble(), mtrap_set(), mapgendata::north(), one_in(), oter_mapgen, place_items(), place_spawns(), point_west, point_zero, points_in_rectangle(), prefix, random_entry(), random_point(), rng(), rotate(), science_room(), SEEX, SEEY, computer::set_access_denied_msg(), set_radiation(), set_temperature(), mapgendata::south(), SOUTH_EDGE, spawn_item(), square_furn(), calendar::start_of_cataclysm, t_bars, t_card_science, t_concrete_wall, t_console, t_cvdbody, t_cvdmachine, t_dirt, t_door_glass_frosted_c, t_door_metal_c, t_door_metal_locked, t_floor, t_fungus_floor_in, t_fungus_wall, t_marloss, t_radio_tower, t_reinforced_door_glass_c, t_reinforced_glass, t_rock_floor, t_sewage, t_slime, t_stairs_down, t_stairs_up, t_strconc_floor, t_thconc_floor, t_thconc_floor_olight, t_water_sh, ter(), ter_set(), terrain, mapgendata::terrain_type(), tr_at(), tr_dissector, tr_portal, trap_set(), type, mapgendata::west(), tripoint::z, and mapgendata::zlevel().

Referenced by draw_map().

◆ draw_line_furn()

void map::draw_line_furn ( const furn_id type,
const point p1,
const point p2 
)

Definition at line 8160 of file map.cpp.

8161{
8162 draw_line( [this, type]( const point & p ) {
8163 this->furn_set( p, type );
8164 }, p1, p2 );
8165}
void draw_line(std::function< void(const point &)>set, const point &p1, const point &p2)

References draw_line(), furn_set(), and type.

Referenced by jmapgen_setmap::apply(), and line_furn().

◆ draw_line_ter()

void map::draw_line_ter ( const ter_id type,
const point p1,
const point p2 
)

Definition at line 8153 of file map.cpp.

8154{
8155 draw_line( [this, type]( const point & p ) {
8156 this->ter_set( p, type );
8157 }, p1, p2 );
8158}

References draw_line(), ter_set(), and type.

Referenced by jmapgen_setmap::apply(), and line().

◆ draw_map()

void map::draw_map ( mapgendata dat)
protected

Definition at line 2884 of file mapgen.cpp.

2885{
2886 const oter_id &terrain_type = dat.terrain_type();
2887 const std::string function_key = terrain_type->get_mapgen_id();
2888 bool found = true;
2889
2890 const bool generated = run_mapgen_func( function_key, dat );
2891
2892 if( !generated ) {
2893 if( is_ot_match( "slimepit", terrain_type, ot_match_type::prefix ) ||
2894 is_ot_match( "slime_pit", terrain_type, ot_match_type::prefix ) ) {
2895 draw_slimepit( dat );
2896 } else if( is_ot_match( "triffid", terrain_type, ot_match_type::prefix ) ) {
2897 draw_triffid( dat );
2898 } else if( is_ot_match( "office", terrain_type, ot_match_type::prefix ) ) {
2899 draw_office_tower( dat );
2900 } else if( is_ot_match( "temple", terrain_type, ot_match_type::prefix ) ) {
2901 draw_temple( dat );
2902 } else if( is_ot_match( "mine", terrain_type, ot_match_type::prefix ) ) {
2903 draw_mine( dat );
2904 } else if( is_ot_match( "anthill", terrain_type, ot_match_type::contains ) ) {
2905 draw_anthill( dat );
2906 } else if( is_ot_match( "lab", terrain_type, ot_match_type::contains ) ) {
2907 draw_lab( dat );
2908 } else {
2909 found = false;
2910 }
2911 }
2912
2913 if( !found ) {
2914 // not one of the hardcoded ones!
2915 // load from JSON???
2916 debugmsg( "Error: tried to generate map for omtype %s, \"%s\" (id_mapgen %s)",
2917 terrain_type.id().c_str(), terrain_type->get_name(), function_key.c_str() );
2918 fill_background( this, t_floor );
2919 }
2920
2921 draw_connections( dat );
2922}
void draw_office_tower(mapgendata &dat)
Definition: mapgen.cpp:2927
void draw_mine(mapgendata &dat)
Definition: mapgen.cpp:4762
void draw_triffid(mapgendata &dat)
Definition: mapgen.cpp:5087
void draw_anthill(mapgendata &dat)
Definition: mapgen.cpp:5025
void draw_slimepit(mapgendata &dat)
Definition: mapgen.cpp:5043
void draw_lab(mapgendata &dat)
Definition: mapgen.cpp:3515
void draw_connections(mapgendata &dat)
Definition: mapgen.cpp:5235
void draw_temple(mapgendata &dat)
Definition: mapgen.cpp:4516
void fill_background(map *m, const ter_id &type)
Definition: mapgen.cpp:6463
bool run_mapgen_func(const std::string &mapgen_id, mapgendata &dat)
Definition: mapgen.cpp:6687
std::string get_name() const
Definition: omdata.h:209
std::string get_mapgen_id() const
Definition: overmap.cpp:773

References string_id< T >::c_str(), contains, debugmsg, draw_anthill(), draw_connections(), draw_lab(), draw_mine(), draw_office_tower(), draw_slimepit(), draw_temple(), draw_triffid(), fill_background(), oter_t::get_mapgen_id(), oter_t::get_name(), int_id< T >::id(), is_ot_match(), prefix, run_mapgen_func(), t_floor, and mapgendata::terrain_type().

Referenced by generate().

◆ draw_maptile()

bool map::draw_maptile ( const catacurses::window w,
const tripoint p,
const maptile tile,
const drawsq_params params 
) const
private

Internal version of the drawsq.

Keeps a cached maptile for less re-getting. Returns false if it has drawn all it should, true if draw_from_above should be called after.

Definition at line 5835 of file map.cpp.

5837{
5838 drawsq_params param = params;
5839 nc_color tercol;
5840 const ter_t &curr_ter = curr_maptile.get_ter_t();
5841 const furn_t &curr_furn = curr_maptile.get_furn_t();
5842 const trap &curr_trap = curr_maptile.get_trap().obj();
5843 const field &curr_field = curr_maptile.get_field();
5844 int sym;
5845 bool hi = false;
5846 bool graf = false;
5847 bool draw_item_sym = false;
5848
5849 int terrain_sym;
5850 if( curr_ter.has_flag( TFLAG_AUTO_WALL_SYMBOL ) ) {
5851 terrain_sym = determine_wall_corner( p );
5852 } else {
5853 terrain_sym = curr_ter.symbol();
5854 }
5855
5856 if( curr_furn.id ) {
5857 sym = curr_furn.symbol();
5858 tercol = curr_furn.color();
5859 } else {
5860 sym = terrain_sym;
5861 tercol = curr_ter.color();
5862 }
5863 if( curr_ter.has_flag( TFLAG_SWIMMABLE ) && curr_ter.has_flag( TFLAG_DEEP_WATER ) &&
5864 !g->u.is_underwater() ) {
5865 param.show_items( false ); // Can only see underwater items if WE are underwater
5866 }
5867 // If there's a trap here, and we have sufficient perception, draw that instead
5868 if( curr_trap.can_see( p, g->u ) ) {
5869 tercol = curr_trap.color;
5870 if( curr_trap.sym == '%' ) {
5871 switch( rng( 1, 5 ) ) {
5872 case 1:
5873 sym = '*';
5874 break;
5875 case 2:
5876 sym = '0';
5877 break;
5878 case 3:
5879 sym = '8';
5880 break;
5881 case 4:
5882 sym = '&';
5883 break;
5884 case 5:
5885 sym = '+';
5886 break;
5887 }
5888 } else {
5889 sym = curr_trap.sym;
5890 }
5891 }
5892 if( curr_field.field_count() > 0 ) {
5893 const field_type_id &fid = curr_field.displayed_field_type();
5894 const field_entry *fe = curr_field.find_field( fid );
5895 const auto field_symbol = fid->get_symbol();
5896 if( field_symbol == "&" || fe == nullptr ) {
5897 // Do nothing, a '&' indicates invisible fields.
5898 } else if( field_symbol == "*" ) {
5899 // A random symbol.
5900 switch( rng( 1, 5 ) ) {
5901 case 1:
5902 sym = '*';
5903 break;
5904 case 2:
5905 sym = '0';
5906 break;
5907 case 3:
5908 sym = '8';
5909 break;
5910 case 4:
5911 sym = '&';
5912 break;
5913 case 5:
5914 sym = '+';
5915 break;
5916 }
5917 } else {
5918 // A field symbol '%' indicates the field should not hide
5919 // items/terrain. When the symbol is not '%' it will
5920 // hide items (the color is still inverted if there are items,
5921 // but the tile symbol is not changed).
5922 // draw_item_sym indicates that the item symbol should be used
5923 // even if sym is not '.'.
5924 // As we don't know at this stage if there are any items
5925 // (that are visible to the player!), we always set the symbol.
5926 // If there are items and the field does not hide them,
5927 // the code handling items will override it.
5928 draw_item_sym = ( field_symbol == "'%" );
5929 // If field display_priority is > 1, and the field is set to hide items,
5930 //draw the field as it obscures what's under it.
5931 if( ( field_symbol != "%" && fid.obj().priority > 1 ) || ( field_symbol != "%" &&
5932 sym == '.' ) ) {
5933 // default terrain '.' and
5934 // non-default field symbol -> field symbol overrides terrain
5935 sym = field_symbol[0];
5936 }
5937 tercol = fe->color();
5938 }
5939 }
5940
5941 // TODO: change the local variable sym to std::string and use it instead of this hack.
5942 // Currently this are different variables because terrain/... uses int as symbol type and
5943 // item now use string. Ideally they should all be strings.
5944 std::string item_sym;
5945
5946 // If there are items here, draw those instead
5947 if( param.show_items() && curr_maptile.get_item_count() > 0 && sees_some_items( p, g->u ) ) {
5948 // if there's furniture/terrain/trap/fields (sym!='.')
5949 // and we should not override it, then only highlight the square
5950 if( sym != '.' && sym != '%' && !draw_item_sym ) {
5951 hi = true;
5952 } else {
5953 // otherwise override with the symbol of the last item
5954 item_sym = curr_maptile.get_uppermost_item().symbol();
5955 if( !draw_item_sym ) {
5956 tercol = curr_maptile.get_uppermost_item().color();
5957 }
5958 if( curr_maptile.get_item_count() > 1 ) {
5959 param.highlight( !param.highlight() );
5960 }
5961 }
5962 }
5963
5964 int memory_sym = sym;
5965 int veh_part = 0;
5966 const vehicle *veh = veh_at_internal( p, veh_part );
5967 if( veh != nullptr ) {
5968 sym = special_symbol( veh->face.dir_symbol( veh->part_sym( veh_part ) ) );
5969 tercol = veh->part_color( veh_part );
5970 item_sym.clear(); // clear the item symbol so `sym` is used instead.
5971
5972 if( !veh->forward_velocity() && !veh->player_in_control( g->u ) ) {
5973 memory_sym = sym;
5974 }
5975 }
5976
5977 if( param.memorize() && check_and_set_seen_cache( p ) ) {
5978 g->u.memorize_symbol( getabs( p ), memory_sym );
5979 }
5980
5981 // If there's graffiti here, change background color
5982 if( curr_maptile.has_graffiti() ) {
5983 graf = true;
5984 }
5985
5986 const auto u_vision = g->u.get_vision_modes();
5987 if( u_vision[BOOMERED] ) {
5988 tercol = c_magenta;
5989 } else if( u_vision[NV_GOGGLES] ) {
5990 tercol = param.bright_light() ? c_white : c_light_green;
5991 } else if( param.low_light() ) {
5992 tercol = c_dark_gray;
5993 } else if( u_vision[DARKNESS] ) {
5994 tercol = c_dark_gray;
5995 }
5996
5997 if( param.highlight() ) {
5998 tercol = invert_color( tercol );
5999 } else if( hi ) {
6000 tercol = hilite( tercol );
6001 } else if( graf ) {
6002 tercol = red_background( tercol );
6003 }
6004
6005 if( item_sym.empty() && sym == ' ' ) {
6006 if( !zlevels || p.z <= -OVERMAP_DEPTH || !curr_ter.has_flag( TFLAG_NO_FLOOR ) ) {
6007 // Print filler symbol
6008 sym = ' ';
6009 tercol = c_black;
6010 } else {
6011 // Draw tile underneath this one instead
6012 return false;
6013 }
6014 }
6015
6016 if( params.output() ) {
6017 if( item_sym.empty() ) {
6018 wputch( w, tercol, sym );
6019 } else {
6020 wprintz( w, tercol, item_sym );
6021 }
6022 }
6023 return true;
6024}
nc_color color() const
Definition: field.cpp:94
field_entry * find_field(const field_type_id &field_type_to_find)
Returns a field entry corresponding to the field_type_id parameter passed in.
Definition: field.cpp:153
field_type_id displayed_field_type() const
Returns field type that should be drawn.
Definition: field.cpp:275
unsigned int field_count() const
Definition: field.cpp:246
bool check_and_set_seen_cache(const tripoint &p) const
Definition: map.h:474
bool sees_some_items(const tripoint &p, const Creature &who) const
Check if creature can see some items at p.
Definition: map.cpp:4715
nc_color part_color(int p, bool exact=false) const
bool player_in_control(const Character &p) const
Definition: vehicle.cpp:277
float forward_velocity() const
nc_color red_background(const nc_color &c)
Definition: color.cpp:515
nc_color hilite(const nc_color &c)
Definition: color.cpp:509
@ TFLAG_SWIMMABLE
Definition: mapdata.h:279
void wprintz(const catacurses::window &w, const nc_color &FG, const std::string &text)
Definition: output.cpp:2043
constexpr drawsq_params & show_items(bool v)
Whether to draw items on the tile.
Definition: map.h:208
int priority
Definition: field_type.h:176
std::string get_symbol(int level=0) const
Definition: field_type.h:195
furn_str_id id
Definition: mapdata.h:490
nc_color color
Definition: trap.h:93
int sym
Definition: trap.h:92

References BOOMERED, drawsq_params::bright_light(), c_black, c_dark_gray, c_light_green, c_magenta, c_white, trap::can_see(), check_and_set_seen_cache(), field_entry::color(), item::color(), map_data_common_t::color(), trap::color, DARKNESS, determine_wall_corner(), tileray::dir_symbol(), field::displayed_field_type(), vehicle::face, field::field_count(), field::find_field(), vehicle::forward_velocity(), g, maptile::get_field(), maptile::get_furn_t(), maptile::get_item_count(), field_type::get_symbol(), maptile::get_ter_t(), maptile::get_trap(), maptile::get_uppermost_item(), getabs(), map_data_common_t::has_flag(), maptile::has_graffiti(), drawsq_params::highlight(), hilite(), furn_t::id, invert_color(), drawsq_params::low_light(), drawsq_params::memorize(), NV_GOGGLES, int_id< T >::obj(), drawsq_params::output(), OVERMAP_DEPTH, vehicle::part_color(), vehicle::part_sym(), vehicle::player_in_control(), field_type::priority, red_background(), rng(), sees_some_items(), drawsq_params::show_items(), special_symbol(), trap::sym, item::symbol(), map_data_common_t::symbol(), TFLAG_AUTO_WALL_SYMBOL, TFLAG_DEEP_WATER, TFLAG_NO_FLOOR, TFLAG_SWIMMABLE, veh_at_internal(), wprintz(), wputch(), tripoint::z, and zlevels.

Referenced by draw(), and drawsq().

◆ draw_mine()

void map::draw_mine ( mapgendata dat)
protected

Definition at line 4762 of file mapgen.cpp.

4763{
4764 const oter_id &terrain_type = dat.terrain_type();
4765 if( terrain_type == "mine" || terrain_type == "mine_down" ) {
4766 if( is_ot_match( "mine", dat.north(), ot_match_type::prefix ) ) {
4767 dat.n_fac = ( one_in( 10 ) ? 0 : -2 );
4768 } else {
4769 dat.n_fac = 4;
4770 }
4771 if( is_ot_match( "mine", dat.east(), ot_match_type::prefix ) ) {
4772 dat.e_fac = ( one_in( 10 ) ? 0 : -2 );
4773 } else {
4774 dat.e_fac = 4;
4775 }
4776 if( is_ot_match( "mine", dat.south(), ot_match_type::prefix ) ) {
4777 dat.s_fac = ( one_in( 10 ) ? 0 : -2 );
4778 } else {
4779 dat.s_fac = 4;
4780 }
4781 if( is_ot_match( "mine", dat.west(), ot_match_type::prefix ) ) {
4782 dat.w_fac = ( one_in( 10 ) ? 0 : -2 );
4783 } else {
4784 dat.w_fac = 4;
4785 }
4786
4787 for( int i = 0; i < SEEX * 2; i++ ) {
4788 for( int j = 0; j < SEEY * 2; j++ ) {
4789 if( i >= dat.w_fac + rng( 0, 2 ) && i <= EAST_EDGE - dat.e_fac - rng( 0, 2 ) &&
4790 j >= dat.n_fac + rng( 0, 2 ) && j <= SOUTH_EDGE - dat.s_fac - rng( 0, 2 ) &&
4791 i + j >= 4 && ( SEEX * 2 - i ) + ( SEEY * 2 - j ) >= 6 ) {
4792 ter_set( point( i, j ), t_rock_floor );
4793 } else {
4794 ter_set( point( i, j ), t_rock );
4795 }
4796 }
4797 }
4798
4799 // Not an entrance; maybe some hazards!
4800 switch( rng( 0, 4 ) ) {
4801 case 0:
4802 break; // Nothing! Lucky!
4803
4804 case 1: {
4805 // Toxic gas
4806 point gas_vent_location( rng( 9, 14 ), rng( 9, 14 ) );
4807 ter_set( point( gas_vent_location ), t_rock );
4808 add_field( { gas_vent_location, abs_sub.z }, fd_gas_vent, 2 );
4809 }
4810 break;
4811
4812 case 2: {
4813 // Lava
4814 point start_location( rng( 6, SEEX ), rng( 6, SEEY ) );
4815 point end_location( rng( SEEX + 1, SEEX * 2 - 7 ), rng( SEEY + 1, SEEY * 2 - 7 ) );
4816 const int num = rng( 2, 4 );
4817 for( int i = 0; i < num; i++ ) {
4818 int lx1 = start_location.x + rng( -1, 1 );
4819 int lx2 = end_location.x + rng( -1, 1 );
4820 int ly1 = start_location.y + rng( -1, 1 );
4821 int ly2 = end_location.y + rng( -1, 1 );
4822 line( this, t_lava, point( lx1, ly1 ), point( lx2, ly2 ) );
4823 }
4824 }
4825 break;
4826
4827 case 3: {
4828 // Wrecked equipment
4829 point wreck_location( rng( 9, 14 ), rng( 9, 14 ) );
4830 for( int i = wreck_location.x - 3; i < wreck_location.x + 3; i++ ) {
4831 for( int j = wreck_location.y - 3; j < wreck_location.y + 3; j++ ) {
4832 if( !one_in( 4 ) ) {
4833 make_rubble( tripoint( i, j, abs_sub.z ), f_wreckage, true );
4834 }
4835 }
4836 }
4837 place_items( item_group_id( "wreckage" ), 70, wreck_location + point( -3, -3 ),
4838 wreck_location + point( 2, 2 ), false, calendar::start_of_cataclysm );
4839 }
4840 break;
4841
4842 case 4: {
4843 // Dead miners
4844 const int num_bodies = rng( 4, 8 );
4845 for( int i = 0; i < num_bodies; i++ ) {
4846 if( const auto body = random_point( *this, [this]( const tripoint & p ) {
4847 return move_cost( p ) == 2;
4848 } ) ) {
4849 add_item( *body, item::make_corpse() );
4850 place_items( item_group_id( "mine_equipment" ), 60, *body, *body,
4852 }
4853 }
4854 }
4855 break;
4856
4857 }
4858
4859 if( terrain_type == "mine_down" ) { // Don't forget to build a slope down!
4860 std::vector<direction> open;
4861 if( dat.n_fac == 4 ) {
4862 open.push_back( direction::NORTH );
4863 }
4864 if( dat.e_fac == 4 ) {
4865 open.push_back( direction::EAST );
4866 }
4867 if( dat.s_fac == 4 ) {
4868 open.push_back( direction::SOUTH );
4869 }
4870 if( dat.w_fac == 4 ) {
4871 open.push_back( direction::WEST );
4872 }
4873
4874 if( open.empty() ) { // We'll have to build it in the center
4875 int tries = 0;
4876 point p;
4877 bool okay = true;
4878 do {
4879 p.x = rng( SEEX - 6, SEEX + 1 );
4880 p.y = rng( SEEY - 6, SEEY + 1 );
4881 okay = true;
4882 for( int i = p.x; ( i <= p.x + 5 ) && okay; i++ ) {
4883 for( int j = p.y; ( j <= p.y + 5 ) && okay; j++ ) {
4884 if( ter( point( i, j ) ) != t_rock_floor ) {
4885 okay = false;
4886 }
4887 }
4888 }
4889 if( !okay ) {
4890 tries++;
4891 }
4892 } while( !okay && tries < 10 );
4893 if( tries == 10 ) { // Clear the area around the slope down
4894 square( this, t_rock_floor, p, p + point( 5, 5 ) );
4895 }
4896 // NOLINTNEXTLINE(cata-use-named-point-constants)
4897 square( this, t_slope_down, p + point( 1, 1 ), p + point( 2, 2 ) );
4898 } else { // We can build against a wall
4899 switch( random_entry( open ) ) {
4900 case direction::NORTH:
4901 square( this, t_rock_floor, point( SEEX - 3, 6 ), point( SEEX + 2, SEEY ) );
4902 line( this, t_slope_down, point( SEEX - 2, 6 ), point( SEEX + 1, 6 ) );
4903 break;
4904 case direction::EAST:
4905 square( this, t_rock_floor, point( SEEX + 1, SEEY - 3 ), point( SEEX * 2 - 7, SEEY + 2 ) );
4906 line( this, t_slope_down, point( SEEX * 2 - 7, SEEY - 2 ), point( SEEX * 2 - 7, SEEY + 1 ) );
4907 break;
4908 case direction::SOUTH:
4909 square( this, t_rock_floor, point( SEEX - 3, SEEY + 1 ), point( SEEX + 2, SEEY * 2 - 7 ) );
4910 line( this, t_slope_down, point( SEEX - 2, SEEY * 2 - 7 ), point( SEEX + 1, SEEY * 2 - 7 ) );
4911 break;
4912 case direction::WEST:
4913 square( this, t_rock_floor, point( 6, SEEY - 3 ), point( SEEX, SEEY + 2 ) );
4914 line( this, t_slope_down, point( 6, SEEY - 2 ), point( 6, SEEY + 1 ) );
4915 break;
4916 default:
4917 break;
4918 }
4919 }
4920 } // Done building a slope down
4921
4922 if( dat.above() == "mine_down" ) { // Don't forget to build a slope up!
4923 std::vector<direction> open;
4924 if( dat.n_fac == 6 && ter( point( SEEX, 6 ) ) != t_slope_down ) {
4925 open.push_back( direction::NORTH );
4926 }
4927 if( dat.e_fac == 6 && ter( point( SEEX * 2 - 7, SEEY ) ) != t_slope_down ) {
4928 open.push_back( direction::EAST );
4929 }
4930 if( dat.s_fac == 6 && ter( point( SEEX, SEEY * 2 - 7 ) ) != t_slope_down ) {
4931 open.push_back( direction::SOUTH );
4932 }
4933 if( dat.w_fac == 6 && ter( point( 6, SEEY ) ) != t_slope_down ) {
4934 open.push_back( direction::WEST );
4935 }
4936
4937 if( open.empty() ) { // We'll have to build it in the center
4938 int tries = 0;
4939 point p;
4940 bool okay = true;
4941 do {
4942 p.x = rng( SEEX - 6, SEEX + 1 );
4943 p.y = rng( SEEY - 6, SEEY + 1 );
4944 okay = true;
4945 for( int i = p.x; ( i <= p.x + 5 ) && okay; i++ ) {
4946 for( int j = p.y; ( j <= p.y + 5 ) && okay; j++ ) {
4947 if( ter( point( i, j ) ) != t_rock_floor ) {
4948 okay = false;
4949 }
4950 }
4951 }
4952 if( !okay ) {
4953 tries++;
4954 }
4955 } while( !okay && tries < 10 );
4956 if( tries == 10 ) { // Clear the area around the slope down
4957 square( this, t_rock_floor, p, p + point( 5, 5 ) );
4958 }
4959 // NOLINTNEXTLINE(cata-use-named-point-constants)
4960 square( this, t_slope_up, p + point( 1, 1 ), p + point( 2, 2 ) );
4961
4962 } else { // We can build against a wall
4963 switch( random_entry( open ) ) {
4964 case direction::NORTH:
4965 line( this, t_slope_up, point( SEEX - 2, 6 ), point( SEEX + 1, 6 ) );
4966 break;
4967 case direction::EAST:
4968 line( this, t_slope_up, point( SEEX * 2 - 7, SEEY - 2 ), point( SEEX * 2 - 7, SEEY + 1 ) );
4969 break;
4970 case direction::SOUTH:
4971 line( this, t_slope_up, point( SEEX - 2, SEEY * 2 - 7 ), point( SEEX + 1, SEEY * 2 - 7 ) );
4972 break;
4973 case direction::WEST:
4974 line( this, t_slope_up, point( 6, SEEY - 2 ), point( 6, SEEY + 1 ) );
4975 break;
4976 default:
4977 break;
4978 }
4979 }
4980 } // Done building a slope up
4981 } else if( terrain_type == "mine_finale" ) {
4982 // Set up the basic chamber
4983 for( int i = 0; i < SEEX * 2; i++ ) {
4984 for( int j = 0; j < SEEY * 2; j++ ) {
4985 if( i > rng( 1, 3 ) && i < SEEX * 2 - rng( 2, 4 ) &&
4986 j > rng( 1, 3 ) && j < SEEY * 2 - rng( 2, 4 ) ) {
4987 ter_set( point( i, j ), t_rock_floor );
4988 } else {
4989 ter_set( point( i, j ), t_rock );
4990 }
4991 }
4992 }
4993
4994 // Now draw the entrance(s)
4995 if( dat.north() == "mine" ) {
4996 square( this, t_rock_floor, point( SEEX, 0 ), point( SEEX + 1, 3 ) );
4997 }
4998
4999 if( dat.east() == "mine" ) {
5000 square( this, t_rock_floor, point( SEEX * 2 - 4, SEEY ), point( EAST_EDGE, SEEY + 1 ) );
5001 }
5002
5003 if( dat.south() == "mine" ) {
5004 square( this, t_rock_floor, point( SEEX, SEEY * 2 - 4 ), point( SEEX + 1, SOUTH_EDGE ) );
5005 }
5006
5007 if( dat.west() == "mine" ) {
5008 square( this, t_rock_floor, point( 0, SEEY ), point( 3, SEEY + 1 ) );
5009 }
5010
5011 // Now, pick and generate a type of finale!
5012 // The Thing dog
5013 const int num_bodies = rng( 4, 8 );
5014 for( int i = 0; i < num_bodies; i++ ) {
5015 point p3( rng( 4, SEEX * 2 - 5 ), rng( 4, SEEX * 2 - 5 ) );
5016 add_item( p3, item::make_corpse() );
5017 place_items( item_group_id( "mine_equipment" ), 60, p3,
5018 p3, false, calendar::start_of_cataclysm );
5019 }
5020 place_spawns( GROUP_DOG_THING, 1, point( SEEX, SEEX ), point( SEEX + 1, SEEX + 1 ), 1, true, true );
5021 spawn_artifact( tripoint( rng( SEEX, SEEX + 1 ), rng( SEEY, SEEY + 1 ), abs_sub.z ) );
5022 }
5023}
void spawn_artifact(const tripoint &p)
Definition: map.cpp:4163
static void open()
furn_id f_wreckage
Definition: mapdata.cpp:1097
ter_id t_rock
Definition: mapdata.cpp:673
ter_id t_lava
Definition: mapdata.cpp:695
void square(map *m, const ter_id &type, const point &p1, const point &p2)
Definition: mapgen.cpp:6471
static const mongroup_id GROUP_DOG_THING("GROUP_DOG_THING")

References mapgendata::above(), abs_sub, add_field(), add_item(), mapgendata::e_fac, EAST, mapgendata::east(), EAST_EDGE, f_wreckage, fd_gas_vent, GROUP_DOG_THING, is_ot_match(), line(), item::make_corpse(), make_rubble(), move_cost(), mapgendata::n_fac, NORTH, mapgendata::north(), num, one_in(), open(), place_items(), place_spawns(), prefix, random_entry(), random_point(), rng(), mapgendata::s_fac, SEEX, SEEY, SOUTH, mapgendata::south(), SOUTH_EDGE, spawn_artifact(), square(), calendar::start_of_cataclysm, t_lava, t_rock, t_rock_floor, t_slope_down, t_slope_up, ter(), ter_set(), mapgendata::terrain_type(), mapgendata::w_fac, WEST, mapgendata::west(), point::x, point::y, and tripoint::z.

Referenced by draw_map().

◆ draw_office_tower()

void map::draw_office_tower ( mapgendata dat)
protected

Definition at line 2927 of file mapgen.cpp.

2928{
2929 const oter_id &terrain_type = dat.terrain_type();
2930 const auto place_office_chairs = [&]() {
2931 int num_chairs = rng( 0, 6 );
2932 for( int i = 0; i < num_chairs; i++ ) {
2933 add_vehicle( vproto_id( "swivel_chair" ), point( rng( 6, 16 ), rng( 6, 16 ) ),
2934 0_degrees, -1, -1, false );
2935 }
2936 };
2937
2938 const auto ter_key = mapf::ter_bind( "E > < R # X G C , _ r V H 6 x % ^ . - | "
2939 "t + = D w T S e o h c d l s", t_elevator, t_stairs_down,
2947 const auto fur_key = mapf::furn_bind( "E > < R # X G C , _ r V H 6 x % ^ . - | "
2948 "t + = D w T S e o h c d l s", f_null, f_null, f_null,
2954 f_null );
2955 const auto b_ter_key = mapf::ter_bind( "E s > < R # X G C , . r V H 6 x % ^ _ - | "
2956 "t + = D w T S e o h c d l", t_elevator, t_rock,
2964 t_floor, t_floor );
2965 const auto b_fur_key = mapf::furn_bind( "E s > < R # X G C , . r V H 6 x % ^ _ - | "
2966 "t + = D w T S e o h c d l", f_null, f_null, f_null,
2973
2974 if( terrain_type == "office_tower_1_entrance" ) {
2975 dat.fill_groundcover();
2977 "ss%|....+...|...|EEED...\n"
2978 "ss%|----|...|...|EEx|...\n"
2979 "ss%Vcdc^|...|-+-|---|...\n"
2980 "ss%Vch..+...............\n"
2981 "ss%V....|...............\n"
2982 "ss%|----|-|-+--ccc--|...\n"
2983 "ss%|..C..C|.....h..r|-+-\n"
2984 "sss=......+..h.....r|...\n"
2985 "ss%|r..CC.|.ddd....r|T.S\n"
2986 "ss%|------|---------|---\n"
2987 "ss%|####################\n"
2988 "ss%|#|------||------|###\n"
2989 "ss%|#|......||......|###\n"
2990 "ss%|||......||......|###\n"
2991 "ss%||x......||......||##\n"
2992 "ss%|||......||......x|##\n"
2993 "ss%|#|......||......||##\n"
2994 "ss%|#|......||......|###\n"
2995 "ss%|#|XXXXXX||XXXXXX|###\n"
2996 "ss%|-|__,,__||__,,__|---\n"
2997 "ss%% x_,,,,_ __,,__ %%\n"
2998 "ss __,,__ _,,,,_ \n"
2999 "ssssss__,,__ss__,,__ssss\n"
3000 "ssssss______ss______ssss\n", ter_key, fur_key );
3001 place_items( item_group_id( "office" ), 75, point( 4, 2 ), point( 6, 2 ), false,
3003 place_items( item_group_id( "office" ), 75, point( 19, 6 ), point( 19, 6 ), false,
3005 place_items( item_group_id( "office" ), 75, point( 12, 8 ), point( 14, 8 ), false,
3007 if( dat.monster_density() > 1 ) {
3009 } else {
3010 place_spawns( GROUP_PLAIN, 2, point( 15, 1 ), point( 22, 7 ), 1, true );
3011 place_spawns( GROUP_PLAIN, 2, point( 15, 1 ), point( 22, 7 ), 0.15 );
3012 place_spawns( GROUP_ZOMBIE_COP, 2, point( 10, 10 ), point( 14, 10 ), 0.1 );
3013 }
3014 place_office_chairs();
3015
3016 if( dat.north() == "office_tower_1" && dat.west() == "office_tower_1" ) {
3017 rotate( 3 );
3018 } else if( dat.north() == "office_tower_1" && dat.east() == "office_tower_1" ) {
3019 rotate( 0 );
3020 } else if( dat.south() == "office_tower_1" && dat.east() == "office_tower_1" ) {
3021 rotate( 1 );
3022 } else if( dat.west() == "office_tower_1" && dat.south() == "office_tower_1" ) {
3023 rotate( 2 );
3024 }
3025 } else if( terrain_type == "office_tower_1" ) {
3026 // Init to grass & dirt;
3027 dat.fill_groundcover();
3028 if( ( dat.south() == "office_tower_1_entrance" && dat.east() == "office_tower_1" ) ||
3029 ( dat.north() == "office_tower_1" && dat.east() == "office_tower_1_entrance" ) ||
3030 ( dat.west() == "office_tower_1" && dat.north() == "office_tower_1_entrance" ) ||
3031 ( dat.south() == "office_tower_1" && dat.west() == "office_tower_1_entrance" ) ) {
3033 " ssssssssssssssssssssssss\n"
3034 "ssssssssssssssssssssssss\n"
3035 "ss \n"
3036 "ss%%%%%%%%%%%%%%%%%%%%%%\n"
3037 "ss%|-HH-|-HH-|-HH-|HH|--\n"
3038 "ss%Vdcxl|dxdl|lddx|..|.S\n"
3039 "ss%Vdh..|dh..|..hd|..+..\n"
3040 "ss%|-..-|-..-|-..-|..|--\n"
3041 "ss%V.................|.T\n"
3042 "ss%V.................|..\n"
3043 "ss%|-..-|-..-|-..-|..|--\n"
3044 "ss%V.h..|..hd|..hd|..|..\n"
3045 "ss%Vdxdl|^dxd|.xdd|..G..\n"
3046 "ss%|----|----|----|..G..\n"
3047 "ss%|llll|..htth......|..\n"
3048 "ss%V.................|..\n"
3049 "ss%V.ddd..........|+-|..\n"
3050 "ss%|..hd|.hh.ceocc|.l|..\n"
3051 "ss%|----|---------|--|..\n"
3052 "ss%Vcdcl|...............\n"
3053 "ss%V.h..+...............\n"
3054 "ss%V...^|...|---|---|...\n"
3055 "ss%|----|...|.R>|EEE|...\n"
3056 "ss%|rrrr|...|.R.|EEED...\n", ter_key, fur_key );
3057 if( dat.monster_density() > 1 ) {
3059 } else {
3060 place_spawns( GROUP_PLAIN, 1, point( 5, 7 ), point( 15, 20 ), 0.1 );
3061 }
3062 place_items( item_group_id( "office" ), 75, point( 4, 23 ), point( 7, 23 ), false,
3064 place_items( item_group_id( "office" ), 75, point( 4, 19 ), point( 7, 19 ), false,
3066 place_items( item_group_id( "office" ), 75, point( 4, 14 ), point( 7, 14 ), false,
3068 place_items( item_group_id( "office" ), 75, point( 5, 16 ), point( 7, 16 ), false,
3070 place_items( item_group_id( "fridge" ), 80, point( 14, 17 ), point( 14, 17 ), false,
3072 place_items( item_group_id( "cleaning" ), 75, point( 19, 17 ), point( 20, 17 ), false,
3074 place_items( item_group_id( "cubical_office" ), 75, point( 6, 12 ), point( 7, 12 ), false,
3076 place_items( item_group_id( "cubical_office" ), 75, point( 12, 11 ), point( 12, 12 ), false,
3078 place_items( item_group_id( "cubical_office" ), 75, point( 16, 11 ), point( 17, 12 ), false,
3080 place_items( item_group_id( "cubical_office" ), 75, point( 4, 5 ), point( 5, 5 ), false,
3082 place_items( item_group_id( "cubical_office" ), 75, point( 11, 5 ), point( 12, 5 ), false,
3084 place_items( item_group_id( "cubical_office" ), 75, point( 14, 5 ), point( 16, 5 ), false,
3086 place_office_chairs();
3087
3088 if( dat.west() == "office_tower_1_entrance" ) {
3089 rotate( 1 );
3090 }
3091 if( dat.north() == "office_tower_1_entrance" ) {
3092 rotate( 2 );
3093 }
3094 if( dat.east() == "office_tower_1_entrance" ) {
3095 rotate( 3 );
3096 }
3097 } else if( ( dat.west() == "office_tower_1_entrance" && dat.north() == "office_tower_1" ) ||
3098 ( dat.north() == "office_tower_1_entrance" && dat.east() == "office_tower_1" ) ||
3099 ( dat.west() == "office_tower_1" && dat.south() == "office_tower_1_entrance" ) ||
3100 ( dat.south() == "office_tower_1" && dat.east() == "office_tower_1_entrance" ) ) {
3102 "...DEEE|...|..|-----|%ss\n"
3103 "...|EEE|...|..|^...lV%ss\n"
3104 "...|---|-+-|......hdV%ss\n"
3105 "...........G..|..dddV%ss\n"
3106 "...........G..|-----|%ss\n"
3107 ".......|---|..|...ddV%ss\n"
3108 "|+-|...|...+......hdV%ss\n"
3109 "|.l|...|rr.|.^|l...dV%ss\n"
3110 "|--|...|---|--|-----|%ss\n"
3111 "|...........c.......V%ss\n"
3112 "|.......cxh.c.#####.Vsss\n"
3113 "|.......ccccc.......Gsss\n"
3114 "|...................Gsss\n"
3115 "|...................Vsss\n"
3116 "|#..................Gsss\n"
3117 "|#..................Gsss\n"
3118 "|#..................Vsss\n"
3119 "|#............#####.V%ss\n"
3120 "|...................|%ss\n"
3121 "--HHHHHGGHHGGHHHHH--|%ss\n"
3122 "%%%%% ssssssss %%%%%%%ss\n"
3123 " ssssssss ss\n"
3124 "ssssssssssssssssssssssss\n"
3125 "ssssssssssssssssssssssss\n", ter_key, fur_key );
3126 place_items( item_group_id( "office" ), 75, point( 19, 1 ), point( 19, 3 ), false,
3128 place_items( item_group_id( "office" ), 75, point( 17, 3 ), point( 18, 3 ), false,
3130 place_items( item_group_id( "office" ), 90, point( 8, 7 ), point( 9, 7 ), false,
3132 place_items( item_group_id( "cubical_office" ), 75, point( 19, 5 ), point( 19, 7 ), false,
3134 place_items( item_group_id( "cleaning" ), 80, point( 1, 7 ), point( 2, 7 ), false,
3136 if( dat.monster_density() > 1 ) {
3137 place_spawns( GROUP_ZOMBIE, 2, point_zero, point( 14, 10 ), dat.monster_density() );
3138 } else {
3139 place_spawns( GROUP_PLAIN, 1, point( 10, 10 ), point( 14, 10 ), 0.15 );
3140 place_spawns( GROUP_ZOMBIE_COP, 2, point( 10, 10 ), point( 14, 10 ), 0.1 );
3141 }
3142 place_office_chairs();
3143
3144 if( dat.north() == "office_tower_1_entrance" ) {
3145 rotate( 1 );
3146 }
3147 if( dat.east() == "office_tower_1_entrance" ) {
3148 rotate( 2 );
3149 }
3150 if( dat.south() == "office_tower_1_entrance" ) {
3151 rotate( 3 );
3152 }
3153 } else {
3155 "ssssssssssssssssssssssss\n"
3156 "ssssssssssssssssssssssss\n"
3157 " ss\n"
3158 "%%%%%%%%%%%%%%%%%%%%%%ss\n"
3159 "--|---|--HHHH-HHHH--|%ss\n"
3160 ".T|..l|............^|%ss\n"
3161 "..|-+-|...hhhhhhh...V%ss\n"
3162 "--|...G...ttttttt...V%ss\n"
3163 ".S|...G...ttttttt...V%ss\n"
3164 "..+...|...hhhhhhh...V%ss\n"
3165 "--|...|.............|%ss\n"
3166 "..|...|-------------|%ss\n"
3167 "..G....|l.......dxd^|%ss\n"
3168 "..G....G...h....dh..V%ss\n"
3169 "..|....|............V%ss\n"
3170 "..|....|------|llccc|%ss\n"
3171 "..|...........|-----|%ss\n"
3172 "..|...........|...ddV%ss\n"
3173 "..|----|---|......hdV%ss\n"
3174 ".......+...|..|l...dV%ss\n"
3175 ".......|rrr|..|-----|%ss\n"
3176 "...|---|---|..|l.dddV%ss\n"
3177 "...|xEE|.R>|......hdV%ss\n"
3178 "...DEEE|.R.|..|.....V%ss\n", ter_key, fur_key );
3179 spawn_item( point( 18, 15 ), "record_accounting" );
3180 place_items( item_group_id( "cleaning" ), 75, point( 3, 5 ), point( 5, 5 ), false,
3182 place_items( item_group_id( "office" ), 75, point( 10, 7 ), point( 16, 8 ), false,
3184 place_items( item_group_id( "cubical_office" ), 75, point( 15, 15 ), point( 19, 15 ), false,
3186 place_items( item_group_id( "cubical_office" ), 75, point( 16, 12 ), point( 16, 13 ), false,
3188 place_items( item_group_id( "cubical_office" ), 75, point( 17, 19 ), point( 19, 19 ), false,
3190 place_items( item_group_id( "office" ), 75, point( 17, 21 ), point( 19, 21 ), false,
3192 place_items( item_group_id( "office" ), 75, point( 16, 11 ), point( 17, 12 ), false,
3194 place_items( item_group_id( "cleaning" ), 75, point( 8, 20 ), point( 10, 20 ), false,
3196 if( dat.monster_density() > 1 ) {
3198 } else {
3199 place_spawns( GROUP_PLAIN, 1, point_zero, point( 9, 15 ), 0.1 );
3200 }
3201 place_office_chairs();
3202
3203 if( dat.west() == "office_tower_1" && dat.north() == "office_tower_1" ) {
3204 rotate( 1 );
3205 } else if( dat.east() == "office_tower_1" && dat.north() == "office_tower_1" ) {
3206 rotate( 2 );
3207 } else if( dat.east() == "office_tower_1" && dat.south() == "office_tower_1" ) {
3208 rotate( 3 );
3209 }
3210 }
3211 } else if( terrain_type == "office_tower_b_entrance" ) {
3212 dat.fill_groundcover();
3214 "sss|........|...|EEED___\n"
3215 "sss|........|...|EEx|___\n"
3216 "sss|........|-+-|---|HHG\n"
3217 "sss|....................\n"
3218 "sss|....................\n"
3219 "sss|....................\n"
3220 "sss|....................\n"
3221 "sss|....,,......,,......\n"
3222 "sss|...,,,,.....,,......\n"
3223 "sss|....,,.....,,,,..xS.\n"
3224 "sss|....,,......,,...SS.\n"
3225 "sss|-|XXXXXX||XXXXXX|---\n"
3226 "sss|s|EEEEEE||EEEEEE|sss\n"
3227 "sss|||EEEEEE||EEEEEE|sss\n"
3228 "sss||xEEEEEE||EEEEEE||ss\n"
3229 "sss|||EEEEEE||EEEEEEx|ss\n"
3230 "sss|s|EEEEEE||EEEEEE||ss\n"
3231 "sss|s|EEEEEE||EEEEEE|sss\n"
3232 "sss|s|------||------|sss\n"
3233 "sss|--------------------\n"
3234 "ssssssssssssssssssssssss\n"
3235 "ssssssssssssssssssssssss\n"
3236 "ssssssssssssssssssssssss\n"
3237 "ssssssssssssssssssssssss\n", ter_key, fur_key );
3238 if( dat.monster_density() > 1 ) {
3240 } else {
3242 }
3243 if( dat.north() == "office_tower_b" && dat.west() == "office_tower_b" ) {
3244 rotate( 3 );
3245 } else if( dat.north() == "office_tower_b" && dat.east() == "office_tower_b" ) {
3246 rotate( 0 );
3247 } else if( dat.south() == "office_tower_b" && dat.east() == "office_tower_b" ) {
3248 rotate( 1 );
3249 } else if( dat.west() == "office_tower_b" && dat.south() == "office_tower_b" ) {
3250 rotate( 2 );
3251 }
3252 } else if( terrain_type == "office_tower_b" ) {
3253 // Init to grass & dirt;
3254 dat.fill_groundcover();
3255 if( ( dat.south() == "office_tower_b_entrance" && dat.east() == "office_tower_b" ) ||
3256 ( dat.north() == "office_tower_b" && dat.east() == "office_tower_b_entrance" ) ||
3257 ( dat.west() == "office_tower_b" && dat.north() == "office_tower_b_entrance" ) ||
3258 ( dat.south() == "office_tower_b" && dat.west() == "office_tower_b_entrance" ) ) {
3260 "ssssssssssssssssssssssss\n"
3261 "ssssssssssssssssssssssss\n"
3262 "sss|--------------------\n"
3263 "sss|,.....,.....,.....,S\n"
3264 "sss|,.....,.....,.....,S\n"
3265 "sss|,.....,.....,.....,S\n"
3266 "sss|,.....,.....,.....,S\n"
3267 "sss|,.....,.....,.....,S\n"
3268 "sss|,.....,.....,.....,S\n"
3269 "sss|....................\n"
3270 "sss|....................\n"
3271 "sss|....................\n"
3272 "sss|....................\n"
3273 "sss|....................\n"
3274 "sss|....................\n"
3275 "sss|...,,...,....,....,S\n"
3276 "sss|..,,,,..,....,....,S\n"
3277 "sss|...,,...,....,....,S\n"
3278 "sss|...,,...,....,....,S\n"
3279 "sss|........,....,....,S\n"
3280 "sss|........,....,....,S\n"
3281 "sss|........|---|---|HHG\n"
3282 "sss|........|.R<|EEE|___\n"
3283 "sss|........|.R.|EEED___\n", b_ter_key, b_fur_key );
3284 if( dat.monster_density() > 1 ) {
3286 } else {
3288 }
3289 if( dat.west() == "office_tower_b_entrance" ) {
3290 rotate( 1 );
3291 if( x_in_y( 1, 5 ) ) {
3292 add_vehicle( vproto_id( "car" ), point( 17, 7 ), 180_degrees );
3293 }
3294 if( x_in_y( 1, 3 ) ) {
3295 add_vehicle( vproto_id( "motorcycle" ), point( 17, 13 ), 180_degrees );
3296 }
3297 if( x_in_y( 1, 5 ) ) {
3298 if( one_in( 3 ) ) {
3299 add_vehicle( vproto_id( "fire_truck" ), point( 6, 13 ), 0_degrees );
3300 } else {
3301 add_vehicle( vproto_id( "pickup" ), point( 17, 19 ), 180_degrees );
3302 }
3303 }
3304 } else if( dat.north() == "office_tower_b_entrance" ) {
3305 rotate( 2 );
3306 if( x_in_y( 1, 5 ) ) {
3307 add_vehicle( vproto_id( "car" ), point( 10, 17 ), 270_degrees );
3308 }
3309 if( x_in_y( 1, 3 ) ) {
3310 add_vehicle( vproto_id( "motorcycle" ), point( 4, 18 ), 270_degrees );
3311 }
3312 if( x_in_y( 1, 5 ) ) {
3313 if( one_in( 3 ) ) {
3314 add_vehicle( vproto_id( "fire_truck" ), point( 6, 13 ), 0_degrees );
3315 } else {
3316 add_vehicle( vproto_id( "pickup" ), point( 16, 17 ), 270_degrees );
3317 }
3318 }
3319 } else if( dat.east() == "office_tower_b_entrance" ) {
3320 rotate( 3 );
3321 if( x_in_y( 1, 5 ) ) {
3322 add_vehicle( vproto_id( "car" ), point( 6, 4 ), 0_degrees );
3323 }
3324 if( x_in_y( 1, 3 ) ) {
3325 add_vehicle( vproto_id( "motorcycle" ), point( 6, 10 ), 180_degrees );
3326 }
3327 if( x_in_y( 1, 5 ) ) {
3328 add_vehicle( vproto_id( "pickup" ), point( 6, 16 ), 0_degrees );
3329 }
3330
3331 } else {
3332 if( x_in_y( 1, 5 ) ) {
3333 add_vehicle( vproto_id( "pickup" ), point( 7, 6 ), 90_degrees );
3334 }
3335 if( x_in_y( 1, 5 ) ) {
3336 add_vehicle( vproto_id( "car" ), point( 14, 6 ), 90_degrees );
3337 }
3338 if( x_in_y( 1, 3 ) ) {
3339 add_vehicle( vproto_id( "motorcycle" ), point( 19, 6 ), 90_degrees );
3340 }
3341 }
3342 } else if( ( dat.west() == "office_tower_b_entrance" && dat.north() == "office_tower_b" ) ||
3343 ( dat.north() == "office_tower_b_entrance" && dat.east() == "office_tower_b" ) ||
3344 ( dat.west() == "office_tower_b" && dat.south() == "office_tower_b_entrance" ) ||
3345 ( dat.south() == "office_tower_b" && dat.east() == "office_tower_b_entrance" ) ) {
3347 "___DEEE|...|...,,...|sss\n"
3348 "___|EEE|...|..,,,,..|sss\n"
3349 "GHH|---|-+-|...,,...|sss\n"
3350 "....................|sss\n"
3351 "....................|sss\n"
3352 "....................|sss\n"
3353 "....................|sss\n"
3354 "....................|sss\n"
3355 "....................|sss\n"
3356 "....................|sss\n"
3357 "....................|sss\n"
3358 "|...................|sss\n"
3359 "|...................|sss\n"
3360 "|,.....,.....,.....,|sss\n"
3361 "|,.....,.....,.....,|sss\n"
3362 "|,.....,.....,.....,|sss\n"
3363 "|,.....,.....,.....,|sss\n"
3364 "|,.....,.....,.....,|sss\n"
3365 "|,.....,.....,.....,|sss\n"
3366 "|-------------------|sss\n"
3367 "ssssssssssssssssssssssss\n"
3368 "ssssssssssssssssssssssss\n"
3369 "ssssssssssssssssssssssss\n"
3370 "ssssssssssssssssssssssss\n", b_ter_key, b_fur_key );
3371 if( dat.monster_density() > 1 ) {
3373 } else {
3375 }
3376 if( dat.north() == "office_tower_b_entrance" ) {
3377 rotate( 1 );
3378 if( x_in_y( 1, 5 ) ) {
3379 add_vehicle( vproto_id( "car" ), point( 8, 15 ), 0_degrees );
3380 }
3381 if( x_in_y( 1, 5 ) ) {
3382 add_vehicle( vproto_id( "pickup" ), point( 7, 10 ), 180_degrees );
3383 }
3384 if( x_in_y( 1, 3 ) ) {
3385 add_vehicle( vproto_id( "beetle" ), point( 7, 3 ), 0_degrees );
3386 }
3387 } else if( dat.east() == "office_tower_b_entrance" ) {
3388 rotate( 2 );
3389 if( x_in_y( 1, 5 ) ) {
3390 if( one_in( 3 ) ) {
3391 add_vehicle( vproto_id( "fire_truck" ), point( 6, 13 ), 0_degrees );
3392 } else {
3393 add_vehicle( vproto_id( "pickup" ), point( 7, 7 ), 270_degrees );
3394 }
3395 }
3396 if( x_in_y( 1, 5 ) ) {
3397 add_vehicle( vproto_id( "car" ), point( 13, 8 ), 90_degrees );
3398 }
3399 if( x_in_y( 1, 3 ) ) {
3400 add_vehicle( vproto_id( "beetle" ), point( 20, 7 ), 90_degrees );
3401 }
3402 } else if( dat.south() == "office_tower_b_entrance" ) {
3403 rotate( 3 );
3404 if( x_in_y( 1, 5 ) ) {
3405 add_vehicle( vproto_id( "pickup" ), point( 16, 7 ), 0_degrees );
3406 }
3407 if( x_in_y( 1, 5 ) ) {
3408 add_vehicle( vproto_id( "car" ), point( 15, 13 ), 180_degrees );
3409 }
3410 if( x_in_y( 1, 3 ) ) {
3411 add_vehicle( vproto_id( "beetle" ), point( 15, 20 ), 180_degrees );
3412 }
3413 } else {
3414 if( x_in_y( 1, 5 ) ) {
3415 add_vehicle( vproto_id( "pickup" ), point( 16, 16 ), 90_degrees );
3416 }
3417 if( x_in_y( 1, 5 ) ) {
3418 add_vehicle( vproto_id( "car" ), point( 9, 15 ), 270_degrees );
3419 }
3420 if( x_in_y( 1, 3 ) ) {
3421 add_vehicle( vproto_id( "beetle" ), point( 4, 16 ), 270_degrees );
3422 }
3423 }
3424 } else {
3426 "ssssssssssssssssssssssss\n"
3427 "ssssssssssssssssssssssss\n"
3428 "--------------------|sss\n"
3429 "S,.....,.....,.....,|sss\n"
3430 "S,.....,.....,.....,|sss\n"
3431 "S,.....,.....,.....,|sss\n"
3432 "S,.....,.....,.....,|sss\n"
3433 "S,.....,.....,.....,|sss\n"
3434 "S,.....,.....,.....,|sss\n"
3435 "....................|sss\n"
3436 "....................|sss\n"
3437 "....................|sss\n"
3438 "....................|sss\n"
3439 "....................|sss\n"
3440 "....................|sss\n"
3441 "S,....,....,........|sss\n"
3442 "S,....,....,........|sss\n"
3443 "S,....,....,........|sss\n"
3444 "S,....,....,........|sss\n"
3445 "S,....,....,........|sss\n"
3446 "S,....,....,........|sss\n"
3447 "GHH|---|---|........|sss\n"
3448 "___|xEE|.R<|........|sss\n"
3449 "___DEEE|.R.|...,,...|sss\n", b_ter_key, b_fur_key );
3450 if( dat.monster_density() > 1 ) {
3452 } else {
3454 }
3455 if( dat.west() == "office_tower_b" && dat.north() == "office_tower_b" ) {
3456 rotate( 1 );
3457 if( x_in_y( 1, 5 ) ) {
3458 if( one_in( 3 ) ) {
3459 add_vehicle( vproto_id( "cube_van" ), point( 17, 4 ), 180_degrees );
3460 } else {
3461 add_vehicle( vproto_id( "cube_van_cheap" ), point( 17, 4 ), 180_degrees );
3462 }
3463 }
3464 if( x_in_y( 1, 5 ) ) {
3465 add_vehicle( vproto_id( "pickup" ), point( 17, 10 ), 180_degrees );
3466 }
3467 if( x_in_y( 1, 3 ) ) {
3468 add_vehicle( vproto_id( "car" ), point( 17, 17 ), 180_degrees );
3469 }
3470 } else if( dat.east() == "office_tower_b" && dat.north() == "office_tower_b" ) {
3471 rotate( 2 );
3472 if( x_in_y( 1, 5 ) ) {
3473 if( one_in( 3 ) ) {
3474 add_vehicle( vproto_id( "cube_van" ), point( 6, 17 ), 270_degrees );
3475 } else {
3476 add_vehicle( vproto_id( "cube_van_cheap" ), point( 6, 17 ), 270_degrees );
3477 }
3478 }
3479 if( x_in_y( 1, 5 ) ) {
3480 add_vehicle( vproto_id( "pickup" ), point( 12, 17 ), 270_degrees );
3481 }
3482 if( x_in_y( 1, 3 ) ) {
3483 add_vehicle( vproto_id( "fire_truck" ), point( 18, 17 ), 270_degrees );
3484 }
3485 } else if( dat.east() == "office_tower_b" && dat.south() == "office_tower_b" ) {
3486 rotate( 3 );
3487 if( x_in_y( 1, 5 ) ) {
3488 add_vehicle( vproto_id( "cube_van_cheap" ), point( 6, 6 ), 0_degrees );
3489 }
3490 if( x_in_y( 1, 5 ) ) {
3491 if( one_in( 3 ) ) {
3492 add_vehicle( vproto_id( "fire_truck" ), point( 6, 13 ), 0_degrees );
3493 } else {
3494 add_vehicle( vproto_id( "pickup" ), point( 6, 13 ), 0_degrees );
3495 }
3496 }
3497 if( x_in_y( 1, 3 ) ) {
3498 add_vehicle( vproto_id( "car" ), point( 5, 19 ), 180_degrees );
3499 }
3500 } else {
3501 if( x_in_y( 1, 5 ) ) {
3502 add_vehicle( vproto_id( "flatbed_truck" ), point( 16, 6 ), 90_degrees );
3503 }
3504 if( x_in_y( 1, 5 ) ) {
3505 add_vehicle( vproto_id( "cube_van_cheap" ), point( 10, 6 ), 90_degrees );
3506 }
3507 if( x_in_y( 1, 3 ) ) {
3508 add_vehicle( vproto_id( "car" ), point( 4, 6 ), 90_degrees );
3509 }
3510 }
3511 }
3512 }
3513}
bool x_in_y(const time_duration &a, const time_duration &b)
Definition: calendar.cpp:521
void fill_groundcover()
Definition: mapgendata.cpp:125
float monster_density() const
Definition: mapgendata.h:90
furn_id f_chair
Definition: mapdata.cpp:1103
ter_id t_door_locked_alarm
Definition: mapdata.cpp:657
furn_id f_fridge
Definition: mapdata.cpp:1106
ter_id t_wall
Definition: mapdata.cpp:646
furn_id f_bookcase
Definition: mapdata.cpp:1107
ter_id t_pavement
Definition: mapdata.cpp:630
furn_id f_desk
Definition: mapdata.cpp:1103
ter_id t_railing
Definition: mapdata.cpp:688
furn_id f_indoor_plant
Definition: mapdata.cpp:1100
ter_id t_pavement_y
Definition: mapdata.cpp:630
ter_id t_wall_glass
Definition: mapdata.cpp:648
furn_id f_crate_c
Definition: mapdata.cpp:1110
furn_id f_toilet
Definition: mapdata.cpp:1101
ter_id t_window
Definition: mapdata.cpp:666
furn_id f_bench
Definition: mapdata.cpp:1104
ter_id t_door_glass_c
Definition: mapdata.cpp:664
ter_id t_console_broken
Definition: mapdata.cpp:704
ter_id t_door_locked
Definition: mapdata.cpp:657
furn_id f_locker
Definition: mapdata.cpp:1106
ter_id t_elevator
Definition: mapdata.cpp:723
furn_id f_sink
Definition: mapdata.cpp:1102
ter_id t_door_c
Definition: mapdata.cpp:656
static const mongroup_id GROUP_ZOMBIE_COP("GROUP_ZOMBIE_COP")
static const mongroup_id GROUP_PLAIN("GROUP_PLAIN")
static const mongroup_id GROUP_ZOMBIE("GROUP_ZOMBIE")
void formatted_set_simple(map *m, const point &start, const char *cstr, const format_effect< ter_id > &ter_b, const format_effect< furn_id > &furn_b)
Set terrain and furniture on the supplied map.
format_effect< furn_id > furn_bind(const char(&characters)[N], Args... ids)
Definition: mapgenformat.h:76
format_effect< ter_id > ter_bind(const char(&characters)[N], Args... ids)
The functions create a mapping of characters to ids, usable with formatted_set_simple.
Definition: mapgenformat.h:66
string_id< vehicle_prototype > vproto_id
Definition: type_id.h:183

References add_vehicle(), mapgendata::east(), EAST_EDGE, f_bench, f_bookcase, f_chair, f_counter, f_crate_c, f_desk, f_fridge, f_indoor_plant, f_locker, f_null, f_rack, f_sink, f_table, f_toilet, mapgendata::fill_groundcover(), mapf::formatted_set_simple(), mapf::furn_bind(), GROUP_PLAIN, GROUP_ZOMBIE, GROUP_ZOMBIE_COP, mapgendata::monster_density(), mapgendata::north(), one_in(), place_items(), place_spawns(), point_zero, rng(), rotate(), mapgendata::south(), SOUTH_EDGE, spawn_item(), calendar::start_of_cataclysm, t_console, t_console_broken, t_door_c, t_door_glass_c, t_door_locked, t_door_locked_alarm, t_door_metal_locked, t_elevator, t_floor, t_pavement, t_pavement_y, t_railing, t_rock, t_shrub, t_sidewalk, t_stairs_down, t_stairs_up, t_wall, t_wall_glass, t_window, mapf::ter_bind(), mapgendata::terrain_type(), mapgendata::west(), and x_in_y().

Referenced by draw_map().

◆ draw_rough_circle_furn()

void map::draw_rough_circle_furn ( const furn_id type,
const point p,
int  rad 
)

Definition at line 8231 of file map.cpp.

8232{
8233 draw_rough_circle( [this, type]( const point & q ) {
8234 this->furn_set( q, type );
8235 }, p, rad );
8236}

References draw_rough_circle(), furn_set(), and type.

Referenced by rough_circle_furn().

◆ draw_rough_circle_ter()

void map::draw_rough_circle_ter ( const ter_id type,
const point p,
int  rad 
)

Definition at line 8224 of file map.cpp.

8225{
8226 draw_rough_circle( [this, type]( const point & q ) {
8227 this->ter_set( q, type );
8228 }, p, rad );
8229}

References draw_rough_circle(), ter_set(), and type.

Referenced by rough_circle().

◆ draw_slimepit()

void map::draw_slimepit ( mapgendata dat)
protected

Definition at line 5043 of file mapgen.cpp.

5044{
5045 const oter_id &terrain_type = dat.terrain_type();
5046 if( is_ot_match( "slimepit", terrain_type, ot_match_type::prefix ) ) {
5047 for( int i = 0; i < SEEX * 2; i++ ) {
5048 for( int j = 0; j < SEEY * 2; j++ ) {
5049 if( !one_in( 10 ) && ( j < dat.n_fac * SEEX ||
5050 i < dat.w_fac * SEEX ||
5051 j > SEEY * 2 - dat.s_fac * SEEY ||
5052 i > SEEX * 2 - dat.e_fac * SEEX ) ) {
5053 ter_set( point( i, j ), ( !one_in( 10 ) ? t_slime : t_rock_floor ) );
5054 } else if( rng( 0, SEEX ) > std::abs( i - SEEX ) && rng( 0, SEEY ) > std::abs( j - SEEY ) ) {
5055 ter_set( point( i, j ), t_slime );
5056 } else if( dat.zlevel() == 0 ) {
5057 ter_set( point( i, j ), t_dirt );
5058 } else {
5059 ter_set( point( i, j ), t_rock_floor );
5060 }
5061 }
5062 }
5063 if( terrain_type == "slimepit_down" ) {
5064 ter_set( point( rng( 3, SEEX * 2 - 4 ), rng( 3, SEEY * 2 - 4 ) ), t_slope_down );
5065 }
5066 if( dat.above() == "slimepit_down" ) {
5067 switch( rng( 1, 4 ) ) {
5068 case 1:
5069 ter_set( point( rng( 0, 2 ), rng( 0, 2 ) ), t_slope_up );
5070 break;
5071 case 2:
5072 ter_set( point( rng( 0, 2 ), SEEY * 2 - rng( 1, 3 ) ), t_slope_up );
5073 break;
5074 case 3:
5075 ter_set( point( SEEX * 2 - rng( 1, 3 ), rng( 0, 2 ) ), t_slope_up );
5076 break;
5077 case 4:
5078 ter_set( point( SEEX * 2 - rng( 1, 3 ), SEEY * 2 - rng( 1, 3 ) ), t_slope_up );
5079 }
5080 }
5081 place_spawns( GROUP_BLOB, 1, point( SEEX, SEEY ), point( SEEX, SEEY ), 0.15 );
5082 place_items( item_group_id( "sewer" ), 40, point_zero, point( EAST_EDGE, SOUTH_EDGE ), true,
5084 }
5085}
static const mongroup_id GROUP_BLOB("GROUP_BLOB")

References mapgendata::above(), mapgendata::e_fac, EAST_EDGE, GROUP_BLOB, is_ot_match(), mapgendata::n_fac, one_in(), place_items(), place_spawns(), point_zero, prefix, rng(), mapgendata::s_fac, SEEX, SEEY, SOUTH_EDGE, calendar::start_of_cataclysm, t_dirt, t_rock_floor, t_slime, t_slope_down, t_slope_up, ter_set(), mapgendata::terrain_type(), mapgendata::w_fac, and mapgendata::zlevel().

Referenced by draw_map().

◆ draw_square_furn()

void map::draw_square_furn ( const furn_id type,
const point p1,
const point p2 
)

Definition at line 8201 of file map.cpp.

8202{
8203 draw_square( [this, type]( const point & p ) {
8204 this->furn_set( p, type );
8205 }, p1, p2 );
8206}
void draw_square(std::function< void(const point &)>set, point p1, point p2)

References draw_square(), furn_set(), and type.

Referenced by jmapgen_setmap::apply(), mission_start::ranch_nurse_1(), mission_start::ranch_nurse_2(), mission_start::ranch_nurse_7(), mission_start::ranch_nurse_8(), and square_furn().

◆ draw_square_ter() [1/3]

◆ draw_square_ter() [2/3]

void map::draw_square_ter ( const weighted_int_list< ter_id > &  f,
const point p1,
const point p2 
)

Definition at line 8215 of file map.cpp.

8217{
8218 draw_square( [this, f]( const point & p ) {
8219 const ter_id *tid = f.pick();
8220 this->ter_set( p, tid != nullptr ? *tid : t_null );
8221 }, p1, p2 );
8222}
ter_id t_null
Definition: mapdata.cpp:623
const T * pick(unsigned int randi) const
This will return a pointer to an object from the list randomly selected and biased by weight.
Definition: weighted_list.h:94

References draw_square(), weighted_list< W, T >::pick(), t_null, and ter_set().

◆ draw_square_ter() [3/3]

void map::draw_square_ter ( ter_id(*)()  f,
const point p1,
const point p2 
)

Definition at line 8208 of file map.cpp.

8209{
8210 draw_square( [this, f]( const point & p ) {
8211 this->ter_set( p, f() );
8212 }, p1, p2 );
8213}

References draw_square(), and ter_set().

◆ draw_temple()

void map::draw_temple ( mapgendata dat)
protected

Definition at line 4516 of file mapgen.cpp.

4517{
4518 const oter_id &terrain_type = dat.terrain_type();
4519 if( terrain_type == "temple" || terrain_type == "temple_stairs" ) {
4520 if( dat.zlevel() == 0 ) {
4521 // Ground floor
4522 // TODO: More varieties?
4523 fill_background( this, t_dirt );
4524 square( this, t_grate, point( SEEX - 1, SEEY - 1 ), point( SEEX, SEEX ) );
4525 ter_set( point( SEEX + 1, SEEY + 1 ), t_pedestal_temple );
4526 } else {
4527 // Underground! Shit's about to get interesting!
4528 // Start with all rock floor
4530 // We always start at the south and go north.
4531 // We use (y / 2 + z) % 4 to guarantee that rooms don't repeat.
4532 switch( 1 + std::abs( abs_sub.y / 2 + dat.zlevel() + 4 ) % 4 ) { // TODO: More varieties!
4533
4534 case 1:
4535 // Flame bursts
4536 square( this, t_rock, point_zero, point( SEEX - 1, SOUTH_EDGE ) );
4537 square( this, t_rock, point( SEEX + 2, 0 ), point( EAST_EDGE, SOUTH_EDGE ) );
4538 for( int i = 2; i < SEEY * 2 - 4; i++ ) {
4539 add_field( {SEEX, i, abs_sub.z}, fd_fire_vent, rng( 1, 3 ) );
4540 add_field( {SEEX + 1, i, abs_sub.z}, fd_fire_vent, rng( 1, 3 ) );
4541 }
4542 break;
4543
4544 case 2:
4545 // Spreading water
4546 square( this, t_water_dp, point( 4, 4 ), point( 5, 5 ) );
4547 // replaced mon_sewer_snake spawn with GROUP_SEWER
4548 // Decide whether a group of only sewer snakes be made, probably not worth it
4549 place_spawns( GROUP_SEWER, 1, point( 4, 4 ), point( 4, 4 ), 1, true );
4550
4551 square( this, t_water_dp, point( SEEX * 2 - 5, 4 ), point( SEEX * 2 - 4, 6 ) );
4552 place_spawns( GROUP_SEWER, 1, point( 1, SEEX * 2 - 5 ), point( 1, SEEX * 2 - 5 ), 1, true );
4553
4554 square( this, t_water_dp, point( 4, SEEY * 2 - 5 ), point( 6, SEEY * 2 - 4 ) );
4555
4556 square( this, t_water_dp, point( SEEX * 2 - 5, SEEY * 2 - 5 ), point( SEEX * 2 - 4,
4557 SEEY * 2 - 4 ) );
4558
4559 square( this, t_rock, point( 0, SEEY * 2 - 2 ), point( SEEX - 1, SOUTH_EDGE ) );
4560 square( this, t_rock, point( SEEX + 2, SEEY * 2 - 2 ), point( EAST_EDGE, SOUTH_EDGE ) );
4561 line( this, t_grate, point( SEEX, 1 ), point( SEEX + 1, 1 ) ); // To drain the water
4562 mtrap_set( this, point( SEEX, SEEY * 2 - 2 ), tr_temple_flood );
4563 mtrap_set( this, point( SEEX + 1, SEEY * 2 - 2 ), tr_temple_flood );
4564 for( int y = 2; y < SEEY * 2 - 2; y++ ) {
4565 for( int x = 2; x < SEEX * 2 - 2; x++ ) {
4566 if( ter( point( x, y ) ) == t_rock_floor && one_in( 4 ) ) {
4567 mtrap_set( this, point( x, y ), tr_temple_flood );
4568 }
4569 }
4570 }
4571 break;
4572
4573 case 3: { // Flipping walls puzzle
4574 line( this, t_rock, point_zero, point( SEEX - 1, 0 ) );
4575 line( this, t_rock, point( SEEX + 2, 0 ), point( EAST_EDGE, 0 ) );
4576 line( this, t_rock, point( SEEX - 1, 1 ), point( SEEX - 1, 6 ) );
4577 line( this, t_bars, point( SEEX + 2, 1 ), point( SEEX + 2, 6 ) );
4578 ter_set( point( 14, 1 ), t_switch_rg );
4579 ter_set( point( 15, 1 ), t_switch_gb );
4580 ter_set( point( 16, 1 ), t_switch_rb );
4581 ter_set( point( 17, 1 ), t_switch_even );
4582 // Start with clear floors--then work backwards to the starting state
4583 line( this, t_floor_red, point( SEEX, 1 ), point( SEEX + 1, 1 ) );
4584 line( this, t_floor_green, point( SEEX, 2 ), point( SEEX + 1, 2 ) );
4585 line( this, t_floor_blue, point( SEEX, 3 ), point( SEEX + 1, 3 ) );
4586 line( this, t_floor_red, point( SEEX, 4 ), point( SEEX + 1, 4 ) );
4587 line( this, t_floor_green, point( SEEX, 5 ), point( SEEX + 1, 5 ) );
4588 line( this, t_floor_blue, point( SEEX, 6 ), point( SEEX + 1, 6 ) );
4589 // Now, randomly choose actions
4590 // Set up an actions vector so that there's not undue repetition
4591 std::vector<int> actions;
4592 actions.push_back( 1 );
4593 actions.push_back( 2 );
4594 actions.push_back( 3 );
4595 actions.push_back( 4 );
4596 actions.push_back( rng( 1, 3 ) );
4597 while( !actions.empty() ) {
4598 const int action = random_entry_removed( actions );
4599 for( int y = 1; y < 7; y++ ) {
4600 for( int x = SEEX; x <= SEEX + 1; x++ ) {
4601 switch( action ) {
4602 case 1:
4603 // Toggle RG
4604 if( ter( point( x, y ) ) == t_floor_red ) {
4605 ter_set( point( x, y ), t_rock_red );
4606 } else if( ter( point( x, y ) ) == t_rock_red ) {
4607 ter_set( point( x, y ), t_floor_red );
4608 } else if( ter( point( x, y ) ) == t_floor_green ) {
4609 ter_set( point( x, y ), t_rock_green );
4610 } else if( ter( point( x, y ) ) == t_rock_green ) {
4611 ter_set( point( x, y ), t_floor_green );
4612 }
4613 break;
4614 case 2:
4615 // Toggle GB
4616 if( ter( point( x, y ) ) == t_floor_blue ) {
4617 ter_set( point( x, y ), t_rock_blue );
4618 } else if( ter( point( x, y ) ) == t_rock_blue ) {
4619 ter_set( point( x, y ), t_floor_blue );
4620 } else if( ter( point( x, y ) ) == t_floor_green ) {
4621 ter_set( point( x, y ), t_rock_green );
4622 } else if( ter( point( x, y ) ) == t_rock_green ) {
4623 ter_set( point( x, y ), t_floor_green );
4624 }
4625 break;
4626 case 3:
4627 // Toggle RB
4628 if( ter( point( x, y ) ) == t_floor_blue ) {
4629 ter_set( point( x, y ), t_rock_blue );
4630 } else if( ter( point( x, y ) ) == t_rock_blue ) {
4631 ter_set( point( x, y ), t_floor_blue );
4632 } else if( ter( point( x, y ) ) == t_floor_red ) {
4633 ter_set( point( x, y ), t_rock_red );
4634 } else if( ter( point( x, y ) ) == t_rock_red ) {
4635 ter_set( point( x, y ), t_floor_red );
4636 }
4637 break;
4638 case 4:
4639 // Toggle Even
4640 if( y % 2 == 0 ) {
4641 if( ter( point( x, y ) ) == t_floor_blue ) {
4642 ter_set( point( x, y ), t_rock_blue );
4643 } else if( ter( point( x, y ) ) == t_rock_blue ) {
4644 ter_set( point( x, y ), t_floor_blue );
4645 } else if( ter( point( x, y ) ) == t_floor_red ) {
4646 ter_set( point( x, y ), t_rock_red );
4647 } else if( ter( point( x, y ) ) == t_rock_red ) {
4648 ter_set( point( x, y ), t_floor_red );
4649 } else if( ter( point( x, y ) ) == t_floor_green ) {
4650 ter_set( point( x, y ), t_rock_green );
4651 } else if( ter( point( x, y ) ) == t_rock_green ) {
4652 ter_set( point( x, y ), t_floor_green );
4653 }
4654 }
4655 break;
4656 }
4657 }
4658 }
4659 }
4660 }
4661 break;
4662
4663 case 4: { // Toggling walls maze
4664 square( this, t_rock, point_zero, point( SEEX - 1, 1 ) );
4665 square( this, t_rock, point( 0, SEEY * 2 - 2 ), point( SEEX - 1, SOUTH_EDGE ) );
4666 square( this, t_rock, point( 0, 2 ), point( SEEX - 4, SEEY * 2 - 3 ) );
4667 square( this, t_rock, point( SEEX + 2, 0 ), point( EAST_EDGE, 1 ) );
4668 square( this, t_rock, point( SEEX + 2, SEEY * 2 - 2 ), point( EAST_EDGE, SOUTH_EDGE ) );
4669 square( this, t_rock, point( SEEX + 5, 2 ), point( EAST_EDGE, SEEY * 2 - 3 ) );
4670 int x = rng( SEEX - 1, SEEX + 2 ), y = 2;
4671 std::vector<point> path; // Path, from end to start
4672 while( x < SEEX - 1 || x > SEEX + 2 || y < SEEY * 2 - 2 ) {
4673 static const std::vector<ter_id> terrains = {
4675 };
4676 path.push_back( point( x, y ) );
4677 ter_set( point( x, y ), random_entry( terrains ) );
4678 if( y == SEEY * 2 - 2 ) {
4679 if( x < SEEX - 1 ) {
4680 x++;
4681 } else if( x > SEEX + 2 ) {
4682 x--;
4683 }
4684 } else {
4685 std::vector<point> next;
4686 for( int nx = x - 1; nx <= x + 1; nx++ ) {
4687 for( int ny = y; ny <= y + 1; ny++ ) {
4688 if( ter( point( nx, ny ) ) == t_rock_floor ) {
4689 next.push_back( point( nx, ny ) );
4690 }
4691 }
4692 }
4693 if( next.empty() ) {
4694 break;
4695 } else {
4696 const point p = random_entry( next );
4697 x = p.x;
4698 y = p.y;
4699 }
4700 }
4701 }
4702 // Now go backwards through path (start to finish), toggling any tiles that need
4703 bool toggle_red = false;
4704 bool toggle_green = false;
4705 bool toggle_blue = false;
4706 for( int i = path.size() - 1; i >= 0; i-- ) {
4707 if( ter( path[i] ) == t_floor_red ) {
4708 toggle_green = !toggle_green;
4709 if( toggle_red ) {
4710 ter_set( path[i], t_rock_red );
4711 }
4712 } else if( ter( path[i] ) == t_floor_green ) {
4713 toggle_blue = !toggle_blue;
4714 if( toggle_green ) {
4715 ter_set( path[i], t_rock_green );
4716 }
4717 } else if( ter( path[i] ) == t_floor_blue ) {
4718 toggle_red = !toggle_red;
4719 if( toggle_blue ) {
4720 ter_set( path[i], t_rock_blue );
4721 }
4722 }
4723 }
4724 // Finally, fill in the rest with random tiles, and place toggle traps
4725 for( int i = SEEX - 3; i <= SEEX + 4; i++ ) {
4726 for( int j = 2; j <= SEEY * 2 - 2; j++ ) {
4727 mtrap_set( this, point( i, j ), tr_temple_toggle );
4728 if( ter( point( i, j ) ) == t_rock_floor ) {
4729 static const std::vector<ter_id> terrains = {
4732 };
4733 ter_set( point( i, j ), random_entry( terrains ) );
4734 }
4735 }
4736 }
4737 }
4738 break;
4739 } // Done with room type switch
4740 // Stairs down if we need them
4741 if( terrain_type == "temple_stairs" ) {
4742 line( this, t_stairs_down, point( SEEX, 0 ), point( SEEX + 1, 0 ) );
4743 }
4744 // Stairs at the south if dat.above() has stairs down.
4745 if( dat.above() == "temple_stairs" ) {
4746 line( this, t_stairs_up, point( SEEX, SOUTH_EDGE ), point( SEEX + 1, SOUTH_EDGE ) );
4747 }
4748
4749 } // Done with underground-only stuff
4750 } else if( terrain_type == "temple_finale" ) {
4751 fill_background( this, t_rock );
4752 square( this, t_rock_floor, point( SEEX - 1, 1 ), point( SEEX + 2, 4 ) );
4753 square( this, t_rock_floor, point( SEEX, 5 ), point( SEEX + 1, SOUTH_EDGE ) );
4754 line( this, t_stairs_up, point( SEEX, SOUTH_EDGE ), point( SEEX + 1, SOUTH_EDGE ) );
4755 spawn_artifact( tripoint( rng( SEEX, SEEX + 1 ), rng( 2, 3 ), abs_sub.z ) );
4756 spawn_artifact( tripoint( rng( SEEX, SEEX + 1 ), rng( 2, 3 ), abs_sub.z ) );
4757 return;
4758
4759 }
4760}
@ action
Definition: dialogue.h:36
ter_id t_switch_even
Definition: mapdata.cpp:727
ter_id t_rock_red
Definition: mapdata.cpp:726
ter_id t_pedestal_temple
Definition: mapdata.cpp:724
ter_id t_floor_blue
Definition: mapdata.cpp:726
ter_id t_grate
Definition: mapdata.cpp:636
ter_id t_switch_rb
Definition: mapdata.cpp:727
ter_id t_rock_green
Definition: mapdata.cpp:726
ter_id t_rock_blue
Definition: mapdata.cpp:726
ter_id t_floor_green
Definition: mapdata.cpp:726
ter_id t_switch_gb
Definition: mapdata.cpp:727
ter_id t_floor_red
Definition: mapdata.cpp:726
ter_id t_switch_rg
Definition: mapdata.cpp:727
static const mongroup_id GROUP_SEWER("GROUP_SEWER")
static const trap_str_id tr_temple_flood("tr_temple_flood")
generic_factory< oter_t > terrains("overmap terrain")
V random_entry_removed(C &container)
Returns a random entry in the container and removes it from the container.
Definition: rng.h:170
trap_id tr_temple_toggle
Definition: trap.cpp:311

References mapgendata::above(), abs_sub, action, add_field(), EAST_EDGE, fd_fire_vent, fill_background(), GROUP_SEWER, line(), mtrap_set(), one_in(), place_spawns(), point_zero, random_entry(), random_entry_removed(), rng(), SEEX, SEEY, SOUTH_EDGE, spawn_artifact(), square(), t_bars, t_dirt, t_floor_blue, t_floor_green, t_floor_red, t_grate, t_pedestal_temple, t_rock, t_rock_blue, t_rock_floor, t_rock_green, t_rock_red, t_stairs_down, t_stairs_up, t_switch_even, t_switch_gb, t_switch_rb, t_switch_rg, t_water_dp, ter(), ter_set(), mapgendata::terrain_type(), anonymous_namespace{overmap.cpp}::terrains, tr_temple_flood, tr_temple_toggle, point::x, point::y, tripoint::y, tripoint::z, and mapgendata::zlevel().

Referenced by draw_map().

◆ draw_triffid()

void map::draw_triffid ( mapgendata dat)
protected

Definition at line 5087 of file mapgen.cpp.

5088{
5089 const oter_id &terrain_type = dat.terrain_type();
5090 if( terrain_type == "triffid_roots" ) {
5092 int node = 0;
5093 int step = 0;
5094 bool node_built[16];
5095 bool done = false;
5096 for( auto &elem : node_built ) {
5097 elem = false;
5098 }
5099 do {
5100 node_built[node] = true;
5101 step++;
5102 point node2( 1 + 6 * ( node % 4 ), 1 + 6 * static_cast<int>( node / 4 ) );
5103 // Clear a 4x4 dirt square
5104 square( this, t_dirt, node2, node2 + point( 3, 3 ) );
5105 // Spawn a monster in there
5106 if( step > 2 ) { // First couple of chambers are safe
5107 int monrng = rng( 1, 25 );
5108 point spawn( node2 + point{ rng( 0, 3 ), rng( 0, 3 ) } );
5109 if( monrng <= 24 ) {
5111 node2 + point( 3, 3 ), 1, true );
5112 } else {
5113 for( int webx = node2.x; webx <= node2.x + 3; webx++ ) {
5114 for( int weby = node2.y; weby <= node2.y + 3; weby++ ) {
5115 add_field( {webx, weby, abs_sub.z}, fd_web, rng( 1, 3 ) );
5116 }
5117 }
5118 place_spawns( GROUP_SPIDER, 1, spawn, spawn, 1, true );
5119 }
5120 }
5121 // TODO: Non-monster hazards?
5122 // Next, pick a cell to move to
5123 std::vector<direction> move;
5124 if( node % 4 > 0 && !node_built[node - 1] ) {
5125 move.push_back( direction::WEST );
5126 }
5127 if( node % 4 < 3 && !node_built[node + 1] ) {
5128 move.push_back( direction::EAST );
5129 }
5130 if( static_cast<int>( node / 4 ) > 0 && !node_built[node - 4] ) {
5131 move.push_back( direction::NORTH );
5132 }
5133 if( static_cast<int>( node / 4 ) < 3 && !node_built[node + 4] ) {
5134 move.push_back( direction::SOUTH );
5135 }
5136
5137 if( move.empty() ) { // Nowhere to go!
5138 square( this, t_slope_down, node2 + point_south_east, node2 + point( 2, 2 ) );
5139 done = true;
5140 } else {
5141 switch( random_entry( move ) ) {
5142 case direction::NORTH:
5143 square( this, t_dirt, node2 + point( 1, -2 ), node2 + point( 2, -1 ) );
5144 node -= 4;
5145 break;
5146 case direction::EAST:
5147 square( this, t_dirt, node2 + point( 4, 1 ), node2 + point( 5, 2 ) );
5148 node++;
5149 break;
5150 case direction::SOUTH:
5151 square( this, t_dirt, node2 + point( 1, 4 ), node2 + point( 2, 5 ) );
5152 node += 4;
5153 break;
5154 case direction::WEST:
5155 square( this, t_dirt, node2 + point( -2, 1 ), node2 + point( -1, 2 ) );
5156 node--;
5157 break;
5158 default:
5159 break;
5160 }
5161 }
5162 } while( !done );
5163 square( this, t_slope_up, point( 2, 2 ), point( 3, 3 ) );
5164 rotate( rng( 0, 3 ) );
5165 } else if( terrain_type == "triffid_finale" ) {
5167 // NOLINTNEXTLINE(cata-use-named-point-constants)
5168 square( this, t_dirt, point( 1, 1 ), point( 4, 4 ) );
5169 square( this, t_dirt, point( 19, 19 ), point( 22, 22 ) );
5170 // Drunken walk until we reach the heart (lower right, [19, 19])
5171 // Chance increases by 1 each turn, and gives the % chance of forcing a move
5172 // to the right or down.
5173 int chance = 0;
5174 int x = 4;
5175 int y = 4;
5176 do {
5177 ter_set( point( x, y ), t_dirt );
5178
5179 if( chance >= 10 && one_in( 10 ) ) { // Add a spawn
5180 place_spawns( GROUP_TRIFFID, 1, point( x, y ), point( x, y ), 1, true );
5181 }
5182
5183 if( rng( 0, 99 ) < chance ) { // Force movement down or to the right
5184 if( x >= 19 ) {
5185 y++;
5186 } else if( y >= 19 ) {
5187 x++;
5188 } else {
5189 if( one_in( 2 ) ) {
5190 x++;
5191 } else {
5192 y++;
5193 }
5194 }
5195 } else {
5196 chance++; // Increase chance of forced movement down/right
5197 // Weigh movement towards directions with lots of existing walls
5198 int chance_west = 0;
5199 int chance_east = 0;
5200 int chance_north = 0;
5201 int chance_south = 0;
5202 for( int dist = 1; dist <= 5; dist++ ) {
5203 if( ter( point( x - dist, y ) ) == t_root_wall ) {
5204 chance_west++;
5205 }
5206 if( ter( point( x + dist, y ) ) == t_root_wall ) {
5207 chance_east++;
5208 }
5209 if( ter( point( x, y - dist ) ) == t_root_wall ) {
5210 chance_north++;
5211 }
5212 if( ter( point( x, y + dist ) ) == t_root_wall ) {
5213 chance_south++;
5214 }
5215 }
5216 int roll = rng( 0, chance_west + chance_east + chance_north + chance_south );
5217 if( roll < chance_west && x > 0 ) {
5218 x--;
5219 } else if( roll < chance_west + chance_east && x < EAST_EDGE ) {
5220 x++;
5221 } else if( roll < chance_west + chance_east + chance_north && y > 0 ) {
5222 y--;
5223 } else if( y < SOUTH_EDGE ) {
5224 y++;
5225 }
5226 } // Done with drunken walk
5227 } while( x < 19 || y < 19 );
5228 // NOLINTNEXTLINE(cata-use-named-point-constants)
5229 square( this, t_slope_up, point( 1, 1 ), point( 2, 2 ) );
5230 place_spawns( GROUP_TRIFFID_HEART, 1, point( 21, 21 ), point( 21, 21 ), 1, true );
5231
5232 }
5233}
ter_id t_root_wall
Definition: mapdata.cpp:684
static const mongroup_id GROUP_TRIFFID_OUTER("GROUP_TRIFFID_OUTER")
static const mongroup_id GROUP_SPIDER("GROUP_SPIDER")
static const mongroup_id GROUP_TRIFFID("GROUP_TRIFFID")
static const mongroup_id GROUP_TRIFFID_HEART("GROUP_TRIFFID_HEART")

References abs_sub, add_field(), detail::digits::done, EAST, EAST_EDGE, fd_web, fill_background(), GROUP_SPIDER, GROUP_TRIFFID, GROUP_TRIFFID_HEART, GROUP_TRIFFID_OUTER, avatar_action::move(), NORTH, one_in(), place_spawns(), point_south_east, random_entry(), rng(), rotate(), SOUTH, SOUTH_EDGE, square(), t_dirt, t_root_wall, t_slope_down, t_slope_up, ter(), ter_set(), mapgendata::terrain_type(), WEST, point::x, point::y, and tripoint::z.

Referenced by draw_map().

◆ drawsq()

void map::drawsq ( const catacurses::window w,
const tripoint p,
const drawsq_params params 
) const

Draw the map tile at the given coordinate.

Called by map::draw().

Parameters
wThe window we are drawing in
pThe tile on this map to draw.
paramsDraw parameters.

Definition at line 5798 of file map.cpp.

5800{
5801 // If we are in tiles mode, the only thing we want to potentially draw is a highlight
5802 if( is_draw_tiles_mode() ) {
5803 if( params.highlight() ) {
5804 g->draw_highlight( p );
5805 }
5806 return;
5807 }
5808
5809 if( !inbounds( p ) ) {
5810 return;
5811 }
5812
5813 const tripoint view_center = params.center();
5814 const int k = p.x + getmaxx( w ) / 2 - view_center.x;
5815 const int j = p.y + getmaxy( w ) / 2 - view_center.y;
5816 wmove( w, point( k, j ) );
5817
5818 const maptile tile = maptile_at( p );
5819 if( draw_maptile( w, p, tile, params ) ) {
5820 return;
5821 }
5822
5823 tripoint below( p.xy(), p.z - 1 );
5824 const maptile tile_below = maptile_at( below );
5825 draw_from_above( w, below, tile_below, params );
5826}
maptile maptile_at(const tripoint &p) const
Definition: map.cpp:197
constexpr drawsq_params & center(const tripoint &p)
Set view center.
Definition: map.h:279

References drawsq_params::center(), draw_from_above(), draw_maptile(), g, catacurses::getmaxx(), catacurses::getmaxy(), drawsq_params::highlight(), inbounds(), is_draw_tiles_mode(), maptile_at(), catacurses::wmove(), tripoint::x, tripoint::xy(), tripoint::y, and tripoint::z.

Referenced by choose_adjacent_highlight(), anonymous_namespace{animation.cpp}::draw_line_curses(), game::draw_look_around_cursor(), editmap::draw_main_ui_overlay(), target_ui::draw_terrain_overlay(), game::pickup(), place_construction(), and editmap::uber_draw_ter().

◆ drop_everything()

void map::drop_everything ( const tripoint p)

Handles map objects of given type (not creatures) falling down.

Returns true if anything changed.

Definition at line 2040 of file map.cpp.

2041{
2042 //Do a suspension check so that there won't be a floor there for the rest of this check.
2043 if( has_flag( "SUSPENDED", p ) ) {
2045 }
2046 if( has_floor( p ) ) {
2047 return;
2048 }
2049
2050 drop_furniture( p );
2051 drop_items( p );
2052 drop_vehicle( p );
2053 drop_fields( p );
2054}
void drop_furniture(const tripoint &p)
Definition: map.cpp:2056
void drop_items(const tripoint &p)
Definition: map.cpp:2198
void drop_vehicle(const tripoint &p)
Definition: map.cpp:2228
void collapse_invalid_suspension(const tripoint &point)
Triggers a recursive collapse of suspended tiles based on their support validity.
Definition: map.cpp:2947
void drop_fields(const tripoint &p)
Definition: map.cpp:2238
bool has_floor(const tripoint &p) const
Definition: map.cpp:2002

References collapse_invalid_suspension(), drop_fields(), drop_furniture(), drop_items(), drop_vehicle(), has_flag(), and has_floor().

Referenced by process_falling().

◆ drop_fields()

void map::drop_fields ( const tripoint p)

Definition at line 2238 of file map.cpp.

2239{
2240 field &fld = field_at( p );
2241 if( fld.field_count() == 0 ) {
2242 return;
2243 }
2244
2245 std::list<field_type_id> dropped;
2246 const tripoint below = p + tripoint_below;
2247 for( const auto &iter : fld ) {
2248 const field_entry &entry = iter.second;
2249 // For now only drop cosmetic fields, which don't warrant per-turn check
2250 // Active fields "drop themselves"
2251 if( entry.decays_on_actualize() ) {
2252 add_field( below, entry.get_field_type(), entry.get_field_intensity(), entry.get_field_age() );
2253 dropped.push_back( entry.get_field_type() );
2254 }
2255 }
2256
2257 for( const auto &entry : dropped ) {
2258 fld.remove_field( entry );
2259 }
2260}
bool decays_on_actualize() const
Definition: field.h:105

References add_field(), field_entry::decays_on_actualize(), field_at(), field::field_count(), field_entry::get_field_age(), field_entry::get_field_intensity(), field_entry::get_field_type(), field::remove_field(), and tripoint_below.

Referenced by drop_everything().

◆ drop_furniture()

void map::drop_furniture ( const tripoint p)

Definition at line 2056 of file map.cpp.

2057{
2058 const furn_id frn = furn( p );
2059 if( frn == f_null ) {
2060 return;
2061 }
2062
2063 enum support_state {
2064 SS_NO_SUPPORT = 0,
2065 SS_BAD_SUPPORT, // TODO: Implement bad, shaky support
2066 SS_GOOD_SUPPORT,
2067 SS_FLOOR, // Like good support, but bash floor instead of tile below
2068 SS_CREATURE
2069 };
2070
2071 // Checks if the tile:
2072 // has floor (supports unconditionally)
2073 // has support below
2074 // has unsupporting furniture below (bad support, things should "slide" if possible)
2075 // has no support and thus allows things to fall through
2076 const auto check_tile = [this]( const tripoint & pt ) {
2077 if( has_floor( pt ) ) {
2078 return SS_FLOOR;
2079 }
2080
2081 tripoint below_dest( pt.xy(), pt.z - 1 );
2082 if( supports_above( below_dest ) ) {
2083 return SS_GOOD_SUPPORT;
2084 }
2085
2086 const furn_id frn_id = furn( below_dest );
2087 if( frn_id != f_null ) {
2088 const furn_t &frn = frn_id.obj();
2089 // Allow crushing tiny/nocollide furniture
2090 if( !frn.has_flag( "TINY" ) && !frn.has_flag( "NOCOLLIDE" ) ) {
2091 return SS_BAD_SUPPORT;
2092 }
2093 }
2094
2095 if( g->critter_at( below_dest ) != nullptr ) {
2096 // Smash a critter
2097 return SS_CREATURE;
2098 }
2099
2100 return SS_NO_SUPPORT;
2101 };
2102
2103 tripoint current( p.xy(), p.z + 1 );
2104 support_state last_state = SS_NO_SUPPORT;
2105 while( last_state == SS_NO_SUPPORT ) {
2106 current.z--;
2107 // Check current tile
2108 last_state = check_tile( current );
2109 }
2110
2111 if( current == p ) {
2112 // Nothing happened
2113 if( last_state != SS_FLOOR ) {
2114 support_dirty( current );
2115 }
2116
2117 return;
2118 }
2119
2120 furn_set( p, f_null );
2121 furn_set( current, frn );
2122
2123 // If it's sealed, we need to drop items with it
2124 const auto &frn_obj = frn.obj();
2125 if( frn_obj.has_flag( TFLAG_SEALED ) && has_items( p ) ) {
2126 auto old_items = i_at( p );
2127 auto new_items = i_at( current );
2128 for( const auto &it : old_items ) {
2129 new_items.insert( it );
2130 }
2131
2132 i_clear( p );
2133 }
2134
2135 // Approximate weight/"bulkiness" based on strength to drag
2136 int weight;
2137 if( frn_obj.has_flag( "TINY" ) || frn_obj.has_flag( "NOCOLLIDE" ) ) {
2138 weight = 5;
2139 } else {
2140 weight = frn_obj.is_movable() ? frn_obj.move_str_req : 20;
2141 }
2142
2143 if( frn_obj.has_flag( "ROUGH" ) || frn_obj.has_flag( "SHARP" ) ) {
2144 weight += 5;
2145 }
2146
2147 // TODO: Balance this.
2148 int dmg = weight * ( p.z - current.z );
2149
2150 if( last_state == SS_FLOOR ) {
2151 // Bash the same tile twice - once for furniture, once for the floor
2152 bash( current, dmg, false, false, true );
2153 bash( current, dmg, false, false, true );
2154 } else if( last_state == SS_BAD_SUPPORT || last_state == SS_GOOD_SUPPORT ) {
2155 bash( current, dmg, false, false, false );
2156 tripoint below( current.xy(), current.z - 1 );
2157 bash( below, dmg, false, false, false );
2158 } else if( last_state == SS_CREATURE ) {
2159 const std::string &furn_name = frn_obj.name();
2160 bash( current, dmg, false, false, false );
2161 tripoint below( current.xy(), current.z - 1 );
2162 Creature *critter = g->critter_at( below );
2163 if( critter == nullptr ) {
2164 debugmsg( "drop_furniture couldn't find creature at %d,%d,%d",
2165 below.x, below.y, below.z );
2166 return;
2167 }
2168
2169 critter->add_msg_player_or_npc( m_bad, _( "Falling %s hits you!" ),
2170 _( "Falling %s hits <npcname>" ),
2171 furn_name );
2172 // TODO: A chance to dodge/uncanny dodge
2173 player *pl = dynamic_cast<player *>( critter );
2174 monster *mon = dynamic_cast<monster *>( critter );
2175 if( pl != nullptr ) {
2176 pl->deal_damage( nullptr, bodypart_id( "torso" ), damage_instance( DT_BASH, rng( dmg / 3, dmg ), 0,
2177 0.5f ) );
2178 pl->deal_damage( nullptr, bodypart_id( "head" ), damage_instance( DT_BASH, rng( dmg / 3, dmg ), 0,
2179 0.5f ) );
2180 pl->deal_damage( nullptr, bodypart_id( "leg_l" ), damage_instance( DT_BASH, rng( dmg / 2, dmg ), 0,
2181 0.4f ) );
2182 pl->deal_damage( nullptr, bodypart_id( "leg_r" ), damage_instance( DT_BASH, rng( dmg / 2, dmg ), 0,
2183 0.4f ) );
2184 pl->deal_damage( nullptr, bodypart_id( "arm_l" ), damage_instance( DT_BASH, rng( dmg / 2, dmg ), 0,
2185 0.4f ) );
2186 pl->deal_damage( nullptr, bodypart_id( "arm_r" ), damage_instance( DT_BASH, rng( dmg / 2, dmg ), 0,
2187 0.4f ) );
2188 } else if( mon != nullptr ) {
2189 // TODO: Monster's armor and size - don't crush hulks with chairs
2190 mon->apply_damage( nullptr, bodypart_id( "torso" ), rng( dmg, dmg * 2 ) );
2191 }
2192 }
2193
2194 // Re-queue for another check, in case bash destroyed something
2195 support_dirty( current );
2196}
bool supports_above(const tripoint &p) const
Does this tile support vehicles and furniture above it.
Definition: map.cpp:2015
void apply_damage(Creature *source, bodypart_id bp, int dam, bool bypass_med=false) override
Definition: monster.cpp:1636

References _, Creature::add_msg_player_or_npc(), monster::apply_damage(), bash(), Character::deal_damage(), debugmsg, DT_BASH, f_null, furn(), furn_set(), g, map_data_common_t::has_flag(), has_floor(), has_items(), i_at(), i_clear(), m_bad, int_id< T >::obj(), rng(), support_dirty(), supports_above(), TFLAG_SEALED, tripoint::x, tripoint::xy(), tripoint::y, and tripoint::z.

Referenced by drop_everything().

◆ drop_items()

void map::drop_items ( const tripoint p)

Definition at line 2198 of file map.cpp.

2199{
2200 if( !has_items( p ) ) {
2201 return;
2202 }
2203
2204 auto items = i_at( p );
2205 // TODO: Make items check the volume tile below can accept
2206 // rather than disappearing if it would be overloaded
2207
2208 tripoint below( p );
2209 while( !has_floor( below ) ) {
2210 below.z--;
2211 }
2212
2213 if( below == p ) {
2214 return;
2215 }
2216
2217 for( const auto &i : items ) {
2218 // TODO: Bash the item up before adding it
2219 // TODO: Bash the creature, terrain, furniture and vehicles on the tile
2220 add_item_or_charges( below, i );
2221 }
2222
2223 // Just to make a sound for now
2224 bash( below, 1 );
2225 i_clear( p );
2226}

References add_item_or_charges(), bash(), has_floor(), has_items(), i_at(), i_clear(), and tripoint::z.

Referenced by drop_everything().

◆ drop_vehicle()

void map::drop_vehicle ( const tripoint p)

Definition at line 2228 of file map.cpp.

2229{
2230 const optional_vpart_position vp = veh_at( p );
2231 if( !vp ) {
2232 return;
2233 }
2234
2235 vp->vehicle().is_falling = true;
2236}

References veh_at().

Referenced by drop_everything().

◆ emit_field()

void map::emit_field ( const tripoint pos,
const emit_id src,
float  mul = 1.0f 
)

Runs one cycle of emission src which may result in propagation of fields.

Parameters
posLocation of emission
srcId of object producing the emission
mulMultiplies the chance and possibly qty (if chance*mul > 100) of the emission

Definition at line 1925 of file map_field.cpp.

1926{
1927 if( !src.is_valid() ) {
1928 return;
1929 }
1930
1931 const float chance = src->chance() * mul;
1932 if( src.is_valid() && x_in_y( chance, 100 ) ) {
1933 const int qty = chance > 100.0f ? roll_remainder( src->qty() * chance / 100.0f ) : src->qty();
1934 propagate_field( pos, src->field(), qty, src->intensity() );
1935 }
1936}
int intensity() const
Intensity of output fields, range [1..maximum_intensity].
Definition: emit.h:34
int qty() const
Units of field to generate per turn subject to chance.
Definition: emit.h:39
int chance() const
Chance to emit each turn, range [1..100].
Definition: emit.h:44
field_type_id field() const
Type of field to emit.
Definition: emit.h:29
void propagate_field(const tripoint &center, const field_type_id &type, int amount, int max_intensity=0)
Definition: map_field.cpp:1938
bool is_valid() const
Returns whether this id is valid, that means whether it refers to an existing object.
Definition: achievement.cpp:65
int roll_remainder(double value)
Definition: rng.cpp:96

References emit::chance(), emit::field(), emit::intensity(), string_id< T >::is_valid(), propagate_field(), emit::qty(), roll_remainder(), and x_in_y().

Referenced by enchantment::activate_passive(), Character::burn_fuel(), game::do_turn(), Character::heat_emission(), Character::passive_power_gen(), projectile_attack(), and emit_actor::use().

◆ examine()

void map::examine ( Character p,
const tripoint pos 
)

Calls the examine function of furniture or terrain at given tile, for given character.

Examines the tile pos, with character as the "examinator" Casts Character to player because player/NPC split isn't done yet.

Will only examine terrain if furniture had iexamine::none as the examine function.

Definition at line 1615 of file map.cpp.

1616{
1617 const auto furn_here = furn( pos ).obj();
1618 if( furn_here.examine != iexamine::none ) {
1619 furn_here.examine( dynamic_cast<player &>( p ), pos );
1620 } else {
1621 ter( pos ).obj().examine( dynamic_cast<player &>( p ), pos );
1622 }
1623}
void none(player &p, const tripoint &examp)
Nothing player can interact with here.
Definition: iexamine.cpp:243
iexamine_function examine
Definition: mapdata.h:398

References map_data_common_t::examine, furn(), iexamine::none(), int_id< T >::obj(), wrapped_vehicle::pos, and ter().

Referenced by npc::pick_up_item(), and water_from().

◆ features() [1/2]

std::string map::features ( const point p)
inline

Definition at line 933 of file map.h.

933 {
934 return features( tripoint( p, abs_sub.z ) );
935 }
std::string features(const tripoint &p)
Definition: map.cpp:1709

References abs_sub, features(), and tripoint::z.

◆ features() [2/2]

std::string map::features ( const tripoint p)

Definition at line 1709 of file map.cpp.

1710{
1711 std::string result;
1712 const auto add = [&]( const std::string & text ) {
1713 if( !result.empty() ) {
1714 result += " ";
1715 }
1716 result += text;
1717 };
1718 const auto add_if = [&]( const bool cond, const std::string & text ) {
1719 if( cond ) {
1720 add( text );
1721 }
1722 };
1723 // This is used in an info window that is 46 characters wide, and is expected
1724 // to take up one line. So, make sure it does that.
1725 // FIXME: can't control length of localized text.
1726 add_if( is_bashable( p ), _( "Smashable." ) );
1727 add_if( has_flag( "DIGGABLE", p ), _( "Diggable." ) );
1728 add_if( has_flag( "PLOWABLE", p ), _( "Plowable." ) );
1729 add_if( has_flag( "ROUGH", p ), _( "Rough." ) );
1730 add_if( has_flag( "UNSTABLE", p ), _( "Unstable." ) );
1731 add_if( has_flag( "SHARP", p ), _( "Sharp." ) );
1732 add_if( has_flag( "FLAT", p ), _( "Flat." ) );
1733 add_if( has_flag( "EASY_DECONSTRUCT", p ), _( "Simple." ) );
1734 add_if( has_flag( "MOUNTABLE", p ), _( "Mountable." ) );
1735 return result;
1736}
bool is_bashable(const tripoint &p, bool allow_floor=false) const
Returns true if there is a bashable vehicle part or the furn/terrain is bashable at p.
Definition: map.cpp:2409
type add(type dir1, type dir2)
Returns a sum of two numbers.
Definition: overmap.cpp:4174

References _, om_direction::add(), has_flag(), and is_bashable().

Referenced by features(), game::print_terrain_info(), and editmap::update_view_with_help().

◆ field_at() [1/2]

field & map::field_at ( const tripoint p)

Gets fields that are here.

Both for querying and edition.

Definition at line 5293 of file map.cpp.

5294{
5295 if( !inbounds( p ) ) {
5296 nulfield = field();
5297 return nulfield;
5298 }
5299
5300 point l;
5301 submap *const current_submap = get_submap_at( p, l );
5302
5303 return current_submap->get_field( l );
5304}
static field nulfield
Definition: map.cpp:139

References submap::get_field(), get_submap_at(), inbounds(), and nulfield.

◆ field_at() [2/2]

const field & map::field_at ( const tripoint p) const

Get the fields that are here.

This is for querying and looking at it only, one can not change the fields.

Parameters
pThe local map coordinates, if out of bounds, returns an empty field.

Definition at line 5277 of file map.cpp.

5278{
5279 if( !inbounds( p ) ) {
5280 nulfield = field();
5281 return nulfield;
5282 }
5283
5284 point l;
5285 submap *const current_submap = get_submap_at( p, l );
5286
5287 return current_submap->get_field( l );
5288}

References submap::get_field(), get_submap_at(), inbounds(), and nulfield.

Referenced by Character::adjacent_tile(), npc::could_move_onto(), dangerous_field_at(), decay_cosmetic_fields(), editmap_hilight::draw(), editmap::draw_main_ui_overlay(), drop_fields(), get_convection_temperature(), game::get_dangerous_tile(), get_field(), get_field_age(), get_field_intensity(), npc::good_escape_direction(), advanced_inv_area::init(), mop_spills(), game::print_fields_info(), process_fields_in_submap(), smash(), and Character::symbol_color().

◆ fill_funnels()

void map::fill_funnels ( const tripoint p,
const time_point since 
)
protected

Try to fill funnel based items here.

Simulates rain from since till now.

Parameters
pThe location in this map where to fill funnels.

Definition at line 6986 of file map.cpp.

6987{
6988 const auto &tr = tr_at( p );
6989 if( !tr.is_funnel() ) {
6990 return;
6991 }
6992 // Note: the inside/outside cache might not be correct at this time
6994 return;
6995 }
6996 auto items = i_at( p );
6997 units::volume maxvolume = 0_ml;
6998 auto biggest_container = items.end();
6999 for( auto candidate = items.begin(); candidate != items.end(); ++candidate ) {
7000 if( candidate->is_funnel_container( maxvolume ) ) {
7001 biggest_container = candidate;
7002 }
7003 }
7004 if( biggest_container != items.end() ) {
7005 retroactively_fill_from_funnel( *biggest_container, tr, since, calendar::turn, getabs( p ) );
7006 }
7007}
void retroactively_fill_from_funnel(item &it, const trap &tr, const time_point &start, const time_point &end, const tripoint &pos)
Determine what a funnel has filled out of game, using funnelcontainer.bday as a starting point.
Definition: weather.cpp:184

References getabs(), has_flag_ter_or_furn(), i_at(), retroactively_fill_from_funnel(), TFLAG_INDOORS, tr_at(), and calendar::turn.

Referenced by actualize().

◆ find_clear_path()

std::vector< tripoint > map::find_clear_path ( const tripoint source,
const tripoint destination 
) const

Iteratively tries Bresenham lines with different biases until it finds a clear line or decides there isn't one.

returns the line found, which may be the straight line, but blocked.

Definition at line 6227 of file map.cpp.

6229{
6230 // TODO: Push this junk down into the Bresenham method, it's already doing it.
6231 const point d( destination.xy() - source.xy() );
6232 const point a( std::abs( d.x ) * 2, std::abs( d.y ) * 2 );
6233 const int dominant = std::max( a.x, a.y );
6234 const int minor = std::min( a.x, a.y );
6235 // This seems to be the method for finding the ideal start value for the error value.
6236 const int ideal_start_offset = minor - dominant / 2;
6237 const int start_sign = ( ideal_start_offset > 0 ) - ( ideal_start_offset < 0 );
6238 // Not totally sure of the derivation.
6239 const int max_start_offset = std::abs( ideal_start_offset ) * 2 + 1;
6240 for( int horizontal_offset = -1; horizontal_offset <= max_start_offset; ++horizontal_offset ) {
6241 int candidate_offset = horizontal_offset * start_sign;
6242 if( sees( source, destination, rl_dist( source, destination ), candidate_offset ) ) {
6243 return line_to( source, destination, candidate_offset, 0 );
6244 }
6245 }
6246 // If we couldn't find a clear LoS, just return the ideal one.
6247 return line_to( source, destination, ideal_start_offset, 0 );
6248}
bool sees(const tripoint &F, const tripoint &T, int range) const
Returns whether F sees T with a view range of range.
Definition: map.cpp:6100

References a, line_to(), minor, rl_dist(), sees(), point::x, tripoint::xy(), and point::y.

Referenced by leap_actor::call(), projectile_attack(), and target_ui::set_cursor_pos().

◆ find_furnitures_with_flag_in_radius()

std::list< tripoint > map::find_furnitures_with_flag_in_radius ( const tripoint center,
size_t  radius,
const std::string &  flag,
size_t  radiusz = 0 
)

returns positions of furnitures with matching flag in the specified radius

Definition at line 8494 of file map.cpp.

8498{
8499 std::list<tripoint> furn_locs;
8500 for( const auto &furn_loc : points_in_radius( center, radius, radiusz ) ) {
8501 if( has_flag_furn( flag, furn_loc ) ) {
8502 furn_locs.push_back( furn_loc );
8503 }
8504 }
8505 return furn_locs;
8506}

References center, has_flag_furn(), and points_in_radius().

Referenced by activity_handlers::operation_do_turn(), and activity_handlers::operation_finish().

◆ flammable_items_at()

bool map::flammable_items_at ( const tripoint p,
int  threshold = 0 
)

Checks if there are any flammable items on the tile.

Parameters
ptile to check
thresholdFuel threshold (lower means worse fuels are accepted).

Definition at line 2620 of file map.cpp.

2621{
2622 if( !has_items( p ) ||
2624 // Sealed containers don't allow fire, so shouldn't allow setting the fire either
2625 return false;
2626 }
2627
2628 for( const auto &i : i_at( p ) ) {
2629 if( i.flammable( threshold ) ) {
2630 return true;
2631 }
2632 }
2633
2634 return false;
2635}
@ TFLAG_ALLOW_FIELD_EFFECT
Definition: mapdata.h:286

References has_flag(), has_items(), i_at(), TFLAG_ALLOW_FIELD_EFFECT, and TFLAG_SEALED.

Referenced by MapExtras::burned_ground_parser(), is_flammable(), firestarter_actor::moves_cost_by_fuel(), and process_fields_in_submap().

◆ free_volume()

units::volume map::free_volume ( const tripoint p)

Definition at line 4209 of file map.cpp.

4210{
4211 return i_at( p ).free_volume();
4212}
units::volume free_volume() const
Definition: item_stack.cpp:141

References item_stack::free_volume(), and i_at().

Referenced by activity_on_turn_move_loot(), add_item_or_charges(), and advanced_inv_area::free_volume().

◆ function_over()

template<typename Functor >
void map::function_over ( const tripoint start,
const tripoint end,
Functor  fun 
) const
private

Runs a functor over given submaps over submaps in the area, getting next submap only when the current one "runs out" rather than every time.

gp in the functor is Grid (like get_submap_at_grid) coordinate of the submap, Will silently clip the area to map bounds.

Parameters
startStarting point for function
endEnd point for function
funFunction to run

Definition at line 8304 of file map.cpp.

8305{
8306 // start and end are just two points, end can be "before" start
8307 // Also clip the area to map area
8308 const tripoint min( std::max( std::min( start.x, end.x ), 0 ), std::max( std::min( start.y, end.y ),
8309 0 ), std::max( std::min( start.z, end.z ), -OVERMAP_DEPTH ) );
8310 const tripoint max( std::min( std::max( start.x, end.x ), SEEX * my_MAPSIZE - 1 ),
8311 std::min( std::max( start.y, end.y ), SEEY * my_MAPSIZE - 1 ), std::min( std::max( start.z, end.z ),
8312 OVERMAP_HEIGHT ) );
8313
8314 // Submaps that contain the bounding points
8315 const point min_sm( min.x / SEEX, min.y / SEEY );
8316 const point max_sm( max.x / SEEX, max.y / SEEY );
8317 // Z outermost, because submaps are flat
8318 tripoint gp;
8319 int &z = gp.z;
8320 int &smx = gp.x;
8321 int &smy = gp.y;
8322 for( z = min.z; z <= max.z; z++ ) {
8323 for( smx = min_sm.x; smx <= max_sm.x; smx++ ) {
8324 for( smy = min_sm.y; smy <= max_sm.y; smy++ ) {
8325 submap const *cur_submap = get_submap_at_grid( { smx, smy, z } );
8326 // Bounds on the submap coordinates
8327 const point sm_min( smx > min_sm.x ? 0 : min.x % SEEX, smy > min_sm.y ? 0 : min.y % SEEY );
8328 const point sm_max( smx < max_sm.x ? SEEX - 1 : max.x % SEEX,
8329 smy < max_sm.y ? SEEY - 1 : max.y % SEEY );
8330
8331 point lp;
8332 int &sx = lp.x;
8333 int &sy = lp.y;
8334 for( sx = sm_min.x; sx <= sm_max.x; ++sx ) {
8335 for( sy = sm_min.y; sy <= sm_max.y; ++sy ) {
8336 const iteration_state rval = fun( gp, cur_submap, lp );
8337 if( rval != ITER_CONTINUE ) {
8338 switch( rval ) {
8339 case ITER_SKIP_ZLEVEL:
8340 smx = my_MAPSIZE + 1;
8341 smy = my_MAPSIZE + 1;
8342 // Fall through
8343 case ITER_SKIP_SUBMAP:
8344 sx = SEEX;
8345 sy = SEEY;
8346 break;
8347 default:
8348 return;
8349 }
8350 }
8351 }
8352 }
8353 }
8354 }
8355 }
8356}
iteration_state
Enum used by functors in function_over to control execution.
Definition: map.h:1937

References get_submap_at_grid(), ITER_CONTINUE, ITER_SKIP_SUBMAP, ITER_SKIP_ZLEVEL, my_MAPSIZE, OVERMAP_DEPTH, OVERMAP_HEIGHT, SEEX, SEEY, sx, sy, point::x, tripoint::x, point::y, tripoint::y, and tripoint::z.

Referenced by scent_blockers().

◆ furn() [1/2]

furn_id map::furn ( const point p) const
inline

Definition at line 827 of file map.h.

827 {
828 return furn( tripoint( p, abs_sub.z ) );
829 }

References abs_sub, furn(), and tripoint::z.

◆ furn() [2/2]

furn_id map::furn ( const tripoint p) const

Definition at line 1343 of file map.cpp.

1344{
1345 if( !inbounds( p ) ) {
1346 return f_null;
1347 }
1348
1349 point l;
1350 submap *const current_submap = get_submap_at( p, l );
1351
1352 return current_submap->get_furn( l );
1353}
furn_id get_furn(const point &p) const
Definition: submap.h:86

References f_null, submap::get_furn(), get_submap_at(), and inbounds().

Referenced by computer_session::action_blood_anal(), computer_session::action_sample(), actualize(), ter_furn_transform::add_all_messages(), iexamine::arcfurnace_empty(), iexamine::arcfurnace_full(), iexamine::autoclave_full(), bash_furn_success(), bash_rating(), bash_resistance(), bash_strength(), bash_ter_furn(), board_up(), MapExtras::burned_ground_parser(), can_construct(), can_examine_at(), can_move_furniture(), construct::check_deconstruct(), vehicle::autodrive_controller::check_drivable(), deploy_tent_actor::check_intact(), close_door(), doors::close_door(), coverage(), create_anomaly(), MapExtras::dead_vegetation_parser(), iexamine::deployed_furniture(), destroy_furn(), displace_items_except_one_liquid(), game::do_turn(), construct::done_deconstruct(), editmap_hilight::draw(), draw_lab(), editmap::draw_main_ui_overlay(), drop_furniture(), Character::env_surgery_bonus(), examine(), game::examine(), game::extended_description(), computer_session::failure_destroy_blood(), farm_action(), feature< furn_id >(), iexamine::fertilize_plant(), talk_function::field_harvest(), activity_handlers::fill_liquid_do_turn(), find_base_construction(), find_potential_computer_point(), iexamine::fireplace(), Character::floor_bedding_warmth(), inventory::form_from_map(), furn(), furn_is_supported(), furnname(), generic_multi_activity_locations(), get_changed_ids_from_update(), activity_handlers::repair_activity_hack::anonymous_namespace{activity_handlers.cpp}::get_fake_tool(), get_furn_transforms_into(), get_hack_type(), get_harvest(), get_harvest_names(), get_keg_capacity(), grab(), game::grabbed_furn_move(), grow_plant(), activity_handlers::hacksaw_finish(), iexamine::harvest_plant(), has_adjacent_furniture_with(), has_flag_furn(), has_furn(), has_pre_terrain(), is_bashable(), is_bashable_furn(), iexamine::kiln_empty(), iexamine::kiln_full(), talk_function::loot_building(), map_stack::max_volume(), mill_activate(), iexamine::mill_finalize(), mill_load_food(), avatar_action::move(), move_cost(), obstacle_coverage(), om_harvest_furn(), iexamine::on_smoke_out(), open_door(), activity_handlers::oxytorch_finish(), tutorial_game::per_turn(), Character::place_corpse(), game::place_player(), mission_start::place_priest_diary(), activity_handlers::plant_seed_finish(), iexamine::portable_structure(), game::print_terrain_info(), process_items_in_submap(), iexamine::quern_examine(), rad_scorch(), iexamine::reload_furniture(), resolve_regional_terrain_and_furniture(), set_item_map_or_vehicle(), smash(), smoker_activate(), smoker_finalize(), smoker_load_food(), iexamine::smoker_options(), fungal_effects::spread_fungus_one_tile(), ter_furn_transform::transform(), editmap::update_view_with_help(), use_charges(), iexamine::use_furn_fake_item(), game::walk_move(), water_from(), and workbench_crafting_speed_multiplier().

◆ furn_set() [1/2]

void map::furn_set ( const point p,
const furn_id new_furniture 
)
inline

Definition at line 839 of file map.h.

839 {
840 furn_set( tripoint( p, abs_sub.z ), new_furniture );
841 }

References abs_sub, furn_set(), and tripoint::z.

◆ furn_set() [2/2]

void map::furn_set ( const tripoint p,
const furn_id new_furniture,
cata::poly_serialized< active_tile_data new_active = nullptr 
)

Sets the furniture at given position.

Parameters
pPosition within the map
new_furnitureId of new furniture
new_activeOverride default active tile of new furniture

Definition at line 1355 of file map.cpp.

1357{
1358 if( !inbounds( p ) ) {
1359 return;
1360 }
1361
1362 point l;
1363 submap *const current_submap = get_submap_at( p, l );
1364 const furn_id old_id = current_submap->get_furn( l );
1365 if( old_id == new_furniture ) {
1366 // Nothing changed
1367 return;
1368 }
1369
1370 current_submap->set_furn( l, new_furniture );
1371
1372 // Set the dirty flags
1373 const furn_t &old_t = old_id.obj();
1374 const furn_t &new_t = new_furniture.obj();
1375
1376 // If player has grabbed this furniture and it's no longer grabbable, release the grab.
1377 if( g->u.get_grab_type() == OBJECT_FURNITURE && g->u.grab_point == p && !new_t.is_movable() ) {
1378 add_msg( _( "The %s you were grabbing is destroyed!" ), old_t.name() );
1379 g->u.grab( OBJECT_NONE );
1380 }
1381 // If a creature was crushed under a rubble -> free it
1382 if( old_id == f_rubble && new_furniture == f_null ) {
1383 Creature *c = g->critter_at( p );
1384 if( c ) {
1385 c->remove_effect( effect_crushed );
1386 }
1387 }
1388 if( new_t.has_flag( "EMITTER" ) ) {
1389 field_furn_locs.push_back( p );
1390 }
1391 if( old_t.transparent != new_t.transparent ) {
1394 }
1395
1396 if( old_t.has_flag( TFLAG_INDOORS ) != new_t.has_flag( TFLAG_INDOORS ) ) {
1398 }
1399
1400 if( old_t.has_flag( TFLAG_NO_FLOOR ) != new_t.has_flag( TFLAG_NO_FLOOR ) ) {
1403 }
1404
1405 if( old_t.has_flag( TFLAG_SUN_ROOF_ABOVE ) != new_t.has_flag( TFLAG_SUN_ROOF_ABOVE ) ) {
1406 set_floor_cache_dirty( p.z + 1 );
1407 }
1408
1410
1412
1413 // TODO: Limit to changes that affect move cost, traps and stairs
1415
1416 // Make sure the furniture falls if it needs to
1417 support_dirty( p );
1418 tripoint above( p.xy(), p.z + 1 );
1419 // Make sure that if we supported something and no longer do so, it falls down
1420 support_dirty( above );
1421
1422 if( old_t.active ) {
1423 current_submap->active_furniture.erase( point_sm_ms( l ) );
1424 // TODO: Only for g->m? Observer pattern?
1426 }
1427 if( new_t.active || new_active ) {
1429 if( new_active ) {
1430 atd = new_active;
1431 } else {
1432 atd = new_t.active->clone();
1433 atd->set_last_updated( calendar::turn );
1434 }
1435 current_submap->active_furniture[point_sm_ms( l )] = atd;
1437 }
1438}
Copyable unique_ptr that writes and reads objects of derived types.
void on_changed(const tripoint_abs_ms &p)
Updates grid at given global map square coordinate.
void set_floor_cache_dirty(const int zlev)
Definition: map.h:436
void set_memory_seen_cache_dirty(const tripoint &p)
Definition: map.h:451
std::map< point_sm_ms, cata::poly_serialized< active_tile_data > > active_furniture
Definition: submap.h:250
void set_furn(const point &p, furn_id furn)
Definition: submap.h:90
coords::coord_point< point, coords::origin::submap, coords::ms > point_sm_ms
Definition: coordinates.h:473
coords::coord_point< tripoint, coords::origin::abs, coords::ms > tripoint_abs_ms
Definition: coordinates.h:486
distribution_grid_tracker & get_distribution_grid_tracker()
Returns distribution grid tracker that is a part of the global game *g.
Definition: game.cpp:12592
@ OBJECT_NONE
Definition: enums.h:187
@ OBJECT_FURNITURE
Definition: enums.h:197
bool is_movable() const
Definition: mapdata.cpp:1516
cata::poly_serialized< active_tile_data > active
Definition: mapdata.h:513
std::string name() const
Definition: mapdata.cpp:511

References _, furn_t::active, submap::active_furniture, add_msg(), c, effect_crushed, f_null, f_rubble, field_furn_locs, g, get_distribution_grid_tracker(), submap::get_furn(), get_submap_at(), getabs(), map_data_common_t::has_flag(), inbounds(), invalidate_max_populated_zlev(), furn_t::is_movable(), map_data_common_t::name(), int_id< T >::obj(), OBJECT_FURNITURE, OBJECT_NONE, distribution_grid_tracker::on_changed(), set_floor_cache_dirty(), submap::set_furn(), set_memory_seen_cache_dirty(), set_outside_cache_dirty(), set_pathfinding_cache_dirty(), set_seen_cache_dirty(), set_transparency_cache_dirty(), support_dirty(), TFLAG_INDOORS, TFLAG_NO_FLOOR, TFLAG_SUN_ROOF_ABOVE, map_data_common_t::transparent, calendar::turn, tripoint::xy(), and tripoint::z.

Referenced by iexamine::aggie_plant(), jmapgen_sign::apply(), jmapgen_vending_machine::apply(), jmapgen_toilet::apply(), jmapgen_gaspump::apply(), jmapgen_furniture::apply(), jmapgen_terrain::apply(), jmapgen_computer::apply(), jmapgen_sealed_item::apply(), jmapgen_setmap::apply(), apply< furn_t >(), iexamine::arcfurnace_empty(), iexamine::arcfurnace_full(), iexamine::autoclave_full(), bash_furn_success(), board_up(), MapExtras::burned_ground_parser(), activity_handlers::clear_rubble_finish(), close_door(), collapse_at(), collapse_invalid_suspension(), complete_construction(), activity_handlers::cracking_finish(), create_anomaly(), MapExtras::dead_vegetation_parser(), iexamine::deployed_furniture(), displace_items_except_one_liquid(), construct::done_deconstruct(), draw_circle_furn(), draw_lab(), draw_line_furn(), draw_rough_circle_furn(), draw_square_furn(), drop_furniture(), iexamine::egg_sack_generic(), farm_action(), iexamine::fertilize_plant(), talk_function::field_harvest(), activity_handlers::fill_liquid_do_turn(), dig_activity_actor::finish(), hacking_activity_actor::finish(), iexamine::fireplace(), iexamine::flower_cactus(), iexamine::flower_dahlia(), iexamine::flower_marloss(), iexamine::flower_poppy(), mapgen_function_json_base::formatted_set_incredibly_simple(), mapf::formatted_set_simple(), iexamine::fungus(), furn_set(), iexamine::fvat_empty(), iexamine::fvat_full(), game::grabbed_furn_move(), grow_plant(), activity_handlers::hacksaw_finish(), iexamine::harvest_furn(), iexamine::harvest_furn_nectar(), iexamine::harvest_plant(), iexamine::kiln_empty(), iexamine::kiln_full(), talk_function::loot_building(), make_rubble(), mapgen_forest(), mapgen_forest_trail_curved(), mapgen_forest_trail_four_way(), mapgen_forest_trail_straight(), mapgen_forest_trail_tee(), mapgen_lake_shore(), mapgen_tutorial(), mill_activate(), iexamine::mill_finalize(), MapExtras::mx_burned_ground(), MapExtras::mx_clay_deposit(), MapExtras::mx_grave(), MapExtras::mx_house_spider(), MapExtras::mx_minefield(), MapExtras::mx_pond(), MapExtras::mx_roadworks(), MapExtras::mx_spider(), MapExtras::mx_supplydrop(), om_harvest_furn(), open_door(), iexamine::open_safe(), activity_handlers::oxytorch_finish(), place_toilet(), place_vending(), activity_handlers::plant_seed_finish(), iexamine::portable_structure(), process_fields_in_submap(), iexamine::quern_examine(), rad_scorch(), mission_start::ranch_nurse_9(), mission_start::ranch_scavenger_3(), resolve_regional_terrain_and_furniture(), iexamine::safe(), science_room(), set(), smoker_activate(), smoker_finalize(), iexamine::smoker_options(), fungal_effects::spread_fungus_one_tile(), ter_or_furn_set(), ter_furn_transform::transform(), deploy_furn_actor::use(), and deploy_tent_actor::use().

◆ furnname() [1/2]

std::string map::furnname ( const point p)
inline

Definition at line 843 of file map.h.

843 {
844 return furnname( tripoint( p, abs_sub.z ) );
845 }
std::string furnname(const tripoint &p)
Definition: map.cpp:1464

References abs_sub, furnname(), and tripoint::z.

◆ furnname() [2/2]

std::string map::furnname ( const tripoint p)

Definition at line 1464 of file map.cpp.

1465{
1466 const furn_t &f = furn( p ).obj();
1467 if( f.has_flag( "PLANT" ) ) {
1468 // Can't use item_stack::only_item() since there might be fertilizer
1469 map_stack items = i_at( p );
1470 const map_stack::iterator seed = std::find_if( items.begin(), items.end(), []( const item & it ) {
1471 return it.is_seed();
1472 } );
1473 if( seed == items.end() ) {
1474 debugmsg( "Missing seed for plant at (%d, %d, %d)", p.x, p.y, p.z );
1475 return "null";
1476 }
1477 const std::string &plant = seed->get_plant_name();
1478 return string_format( "%s (%s)", f.name(), plant );
1479 } else {
1480 return f.name();
1481 }
1482}
iterator begin()
Definition: item_stack.cpp:28
iterator end()
Definition: item_stack.cpp:33
Definition: map.h:101
int seed(player *, item *, bool, const tripoint &)
Definition: iuse.cpp:5990

References item_stack::begin(), debugmsg, item_stack::end(), furn(), map_data_common_t::has_flag(), i_at(), map_data_common_t::name(), int_id< T >::obj(), plant, iuse::seed(), string_format(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by activity_handlers::clear_rubble_finish(), iexamine::egg_sack_generic(), iexamine::fireplace(), iexamine::flower_cactus(), iexamine::flower_dahlia(), iexamine::flower_marloss(), iexamine::flower_poppy(), iexamine::fungus(), furnname(), grab(), harvest_common(), iexamine::locked_object(), iexamine::locked_object_pickable(), name(), game::place_player(), game::print_terrain_info(), iexamine::reload_furniture(), iexamine::rubble(), smash(), and deploy_tent_actor::use().

◆ gas_can_spread_to()

bool map::gas_can_spread_to ( field_entry cur,
const maptile dst 
)
private

Definition at line 211 of file map_field.cpp.

212{
213 const field_entry *tmpfld = dst.get_field().find_field( cur.get_field_type() );
214 // Candidates are existing weaker fields or navigable/flagged tiles with no field.
215 if( tmpfld == nullptr || tmpfld->get_field_intensity() < cur.get_field_intensity() ) {
216 const ter_t &ter = dst.get_ter_t();
217 const furn_t &frn = dst.get_furn_t();
218 return ter_furn_movecost( ter, frn ) > 0 || ter_furn_has_flag( ter, frn, TFLAG_PERMEABLE );
219 }
220 return false;
221}
bool ter_furn_has_flag(const ter_t &ter, const furn_t &furn, const ter_bitflags flag)
Definition: map_field.cpp:161
static int ter_furn_movecost(const ter_t &ter, const furn_t &furn)
Definition: map_field.cpp:166
@ TFLAG_PERMEABLE
Definition: mapdata.h:304
const ter_t & get_ter_t() const
Definition: submap.h:300
const field & get_field() const
Definition: submap.h:304
const furn_t & get_furn_t() const
Definition: submap.h:297

References field::find_field(), maptile::get_field(), field_entry::get_field_intensity(), field_entry::get_field_type(), maptile::get_furn_t(), maptile::get_ter_t(), ter(), ter_furn_has_flag(), ter_furn_movecost(), and TFLAG_PERMEABLE.

Referenced by spread_gas().

◆ gas_spread_to()

void map::gas_spread_to ( field_entry cur,
maptile dst,
const tripoint p 
)
private

Definition at line 223 of file map_field.cpp.

224{
225 const field_type_id current_type = cur.get_field_type();
226 const time_duration current_age = cur.get_field_age();
227 const int current_intensity = cur.get_field_intensity();
228 field_entry *f = dst.find_field( current_type );
229 // Nearby gas grows thicker, and ages are shared.
230 const time_duration age_fraction = current_age / current_intensity;
231 if( f != nullptr ) {
233 cur.set_field_intensity( current_intensity - 1 );
234 f->set_field_age( f->get_field_age() + age_fraction );
235 cur.set_field_age( current_age - age_fraction );
236 // Or, just create a new field.
237 } else if( add_field( p, current_type, 1, 0_turns ) ) {
238 f = dst.find_field( current_type );
239 if( f != nullptr ) {
240 f->set_field_age( age_fraction );
241 } else {
242 debugmsg( "While spreading the gas, field was added but doesn't exist." );
243 }
244 cur.set_field_intensity( current_intensity - 1 );
245 cur.set_field_age( current_age - age_fraction );
246 }
247}
int set_field_intensity(int new_intensity)
Definition: field.cpp:126
field_entry * find_field(const field_type_id &field_to_find)
Definition: submap.h:308

References add_field(), debugmsg, maptile::find_field(), field_entry::get_field_age(), field_entry::get_field_intensity(), field_entry::get_field_type(), field_entry::set_field_age(), and field_entry::set_field_intensity().

Referenced by spread_gas().

◆ generate()

void map::generate ( const tripoint p,
const time_point when 
)

Definition at line 105 of file mapgen.cpp.

106{
107 dbg( DL::Info ) << "map::generate( g[" << g.get() << "], p[" << p <<
108 "], when[" << to_string( when ) << "] )";
109
110 set_abs_sub( p );
111
112 // First we have to create new submaps and initialize them to 0 all over
113 // We create all the submaps, even if we're not a tinymap, so that map
114 // generation which overflows won't cause a crash. At the bottom of this
115 // function, we save the upper-left 4 submaps, and delete the rest.
116 // Mapgen is not z-level aware yet. Only actually initialize current z-level
117 // because other submaps won't be touched.
118 for( int gridx = 0; gridx < my_MAPSIZE; gridx++ ) {
119 for( int gridy = 0; gridy < my_MAPSIZE; gridy++ ) {
120 const size_t grid_pos = get_nonant( { gridx, gridy, p.z } );
121 if( getsubmap( grid_pos ) ) {
122 debugmsg( "Submap already exists at (%d, %d, %d)", gridx, gridy, p.z );
123 continue;
124 }
125 setsubmap( grid_pos, new submap() );
126 // TODO: memory leak if the code below throws before the submaps get stored/deleted!
127 }
128 }
129 // x, and y are submap coordinates, convert to overmap terrain coordinates
130 // TODO: fix point types
131 tripoint_abs_omt abs_omt( sm_to_omt_copy( p ) );
132 oter_id terrain_type = overmap_buffer.ter( abs_omt );
133
134 // This attempts to scale density of zombies inversely with distance from the nearest city.
135 // In other words, make city centers dense and perimeters sparse.
136 float density = 0.0;
137 for( int i = -MON_RADIUS; i <= MON_RADIUS; i++ ) {
138 for( int j = -MON_RADIUS; j <= MON_RADIUS; j++ ) {
139 density += overmap_buffer.ter( abs_omt + point( i, j ) )->get_mondensity();
140 }
141 }
142 density = density / 100;
143
144 mapgendata dat( abs_omt, *this, density, when, nullptr );
145 draw_map( dat );
146
147 // At some point, we should add region information so we can grab the appropriate extras
148 map_extras ex = region_settings_map["default"].region_extras[terrain_type->get_extras()];
149 if( ex.chance > 0 && one_in( ex.chance ) ) {
150 std::string *extra = ex.values.pick();
151 if( extra == nullptr ) {
152 debugmsg( "failed to pick extra for type %s", terrain_type->get_extras() );
153 } else {
154 MapExtras::apply_function( *( ex.values.pick() ), *this, abs_sub );
155 }
156 }
157
158 const auto &spawns = terrain_type->get_static_spawns();
159
160 float spawn_density = 1.0f;
161 if( MonsterGroupManager::is_animal( spawns.group ) ) {
162 spawn_density = get_option< float >( "SPAWN_ANIMAL_DENSITY" );
163 } else {
164 spawn_density = get_option< float >( "SPAWN_DENSITY" );
165 }
166
167 // Apply a multiplier to the number of monsters for really high densities.
168 float odds_after_density = spawns.chance * spawn_density;
169 const float max_odds = 100 - ( 100 - spawns.chance ) / 2.0;
170 float density_multiplier = 1.0f;
171 if( odds_after_density > max_odds ) {
172 density_multiplier = 1.0f * odds_after_density / max_odds;
173 odds_after_density = max_odds;
174 }
175 const int spawn_count = roll_remainder( density_multiplier );
176
177 if( spawns.group && x_in_y( odds_after_density, 100 ) ) {
178 int pop = spawn_count * rng( spawns.population.min, spawns.population.max );
179 for( ; pop > 0; pop-- ) {
180 MonsterGroupResult spawn_details = MonsterGroupManager::GetResultFromGroup( spawns.group, &pop );
181 if( !spawn_details.name ) {
182 continue;
183 }
184 if( const cata::optional<tripoint> pt =
185 random_point( *this, [this]( const tripoint & n ) {
186 return passable( n );
187 } ) ) {
188 add_spawn( spawn_details.name, spawn_details.pack_size, *pt );
189 }
190 }
191 }
192
193 // Okay, we know who are neighbors are. Let's draw!
194 // And finally save used submaps and delete the rest.
195 for( int i = 0; i < my_MAPSIZE; i++ ) {
196 for( int j = 0; j < my_MAPSIZE; j++ ) {
197 dbg( DL::Info ) << "map::generate: submap (" << i << "," << j << ")";
198
199 const tripoint pos( i, j, p.z );
200 if( i <= 1 && j <= 1 ) {
201 saven( pos );
202 } else {
203 const size_t grid_pos = get_nonant( pos );
204 delete getsubmap( grid_pos );
205 setsubmap( grid_pos, nullptr );
206 }
207 }
208 }
209}
std::string to_string(const time_duration &d)
Returns a string showing a duration.
Definition: calendar.cpp:327
static bool is_animal(const mongroup_id &group)
Definition: mongroup.cpp:401
static MonsterGroupResult GetResultFromGroup(const mongroup_id &group, int *quantity=nullptr)
Definition: mongroup.cpp:98
void saven(const tripoint &grid)
Definition: map.cpp:6795
void set_abs_sub(const tripoint &p)
Sets abs_sub, see there.
Definition: map.cpp:8084
void draw_map(mapgendata &dat)
Definition: mapgen.cpp:2884
submap * getsubmap(size_t grididx) const
Get the submap pointer with given index in grid, the index must be valid!
Definition: map.cpp:8094
void add_spawn(const mtype_id &type, int count, const tripoint &p, bool friendly=false, int faction_id=-1, int mission_id=-1, const std::string &name="NONE") const
Definition: mapgen.cpp:5578
bool passable(const tripoint &p) const
Definition: map.cpp:1795
Contains various information regarding the individual mapgen instance (generating a specific part of ...
Definition: mapgendata.h:36
const oter_id & ter(const tripoint_abs_omt &p)
Returns the overmap terrain at the given OMT coordinates.
point sm_to_omt_copy(const point &p)
static constexpr int MON_RADIUS
Definition: mapgen.cpp:99
void apply_function(const string_id< map_extra > &id, map &m, const tripoint &abs_sub)
t_regional_settings_map region_settings_map
Definition: overmap.cpp:186
mtype_id name
Definition: mongroup.h:53
unsigned int chance
weighted_int_list< std::string > values
const std::string & get_extras() const
Definition: omdata.h:241
const overmap_static_spawns & get_static_spawns() const
Definition: omdata.h:249
int get_mondensity() const
Definition: omdata.h:245

References abs_sub, add_spawn(), MapExtras::apply_function(), map_extras::chance, dbg, debugmsg, draw_map(), g, oter_t::get_extras(), oter_t::get_mondensity(), get_nonant(), oter_t::get_static_spawns(), MonsterGroupManager::GetResultFromGroup(), getsubmap(), Info, MonsterGroupManager::is_animal(), MON_RADIUS, my_MAPSIZE, MonsterGroupResult::name, one_in(), overmap_buffer, MonsterGroupResult::pack_size, passable(), random_point(), region_settings_map, rng(), roll_remainder(), saven(), set_abs_sub(), setsubmap(), sm_to_omt_copy(), overmapbuffer::ter(), to_string(), map_extras::values, x_in_y(), and tripoint::z.

Referenced by farm_action(), defense_game::init_map(), loadn(), and editmap::mapgen_preview().

◆ generate_lightmap()

void map::generate_lightmap ( int  zlev)
protected

Definition at line 369 of file lightmap.cpp.

370{
371 auto &map_cache = get_cache( zlev );
372 auto &lm = map_cache.lm;
373 auto &sm = map_cache.sm;
374 auto &outside_cache = map_cache.outside_cache;
375 auto &prev_floor_cache = get_cache( clamp( zlev + 1, -OVERMAP_DEPTH, OVERMAP_DEPTH ) ).floor_cache;
376 bool top_floor = zlev == OVERMAP_DEPTH;
377 std::memset( lm, 0, sizeof( lm ) );
378 std::memset( sm, 0, sizeof( sm ) );
379
380 /* Bulk light sources wastefully cast rays into neighbors; a burning hospital can produce
381 significant slowdown, so for stuff like fire and lava:
382 * Step 1: Store the position and luminance in buffer via add_light_source, for efficient
383 checking of neighbors.
384 * Step 2: After everything else, iterate buffer and apply_light_source only in non-redundant
385 directions
386 * Step 3: ????
387 * Step 4: Profit!
388 */
389 auto &light_source_buffer = map_cache.light_source_buffer;
390 std::memset( light_source_buffer, 0, sizeof( light_source_buffer ) );
391
392 constexpr std::array<int, 4> dir_x = { { 0, -1, 1, 0 } }; // [0]
393 constexpr std::array<int, 4> dir_y = { { -1, 0, 0, 1 } }; // [1][X][2]
394 constexpr std::array<int, 4> dir_d = { { 90, 0, 180, 270 } }; // [3]
395 constexpr std::array<std::array<quadrant, 2>, 4> dir_quadrants = { {
400 }
401 };
402
403 const float natural_light = g->natural_light_level( zlev );
404
405 build_sunlight_cache( zlev );
406
408 for( npc &guy : g->all_npcs() ) {
410 }
411
412 std::vector<std::pair<tripoint, float>> lm_override;
413 // Traverse the submaps in order
414 for( int smx = 0; smx < my_MAPSIZE; ++smx ) {
415 for( int smy = 0; smy < my_MAPSIZE; ++smy ) {
416 const auto cur_submap = get_submap_at_grid( { smx, smy, zlev } );
417
418 for( int sx = 0; sx < SEEX; ++sx ) {
419 for( int sy = 0; sy < SEEY; ++sy ) {
420 const int x = sx + smx * SEEX;
421 const int y = sy + smy * SEEY;
422 const tripoint p( x, y, zlev );
423 // Project light into any openings into buildings.
424 if( !outside_cache[p.x][p.y] || ( !top_floor && prev_floor_cache[p.x][p.y] ) ) {
425 // Apply light sources for external/internal divide
426 for( int i = 0; i < 4; ++i ) {
427 point neighbour = p.xy() + point( dir_x[i], dir_y[i] );
428 if( lightmap_boundaries.contains( neighbour )
429 && outside_cache[neighbour.x][neighbour.y] &&
430 ( top_floor || !prev_floor_cache[neighbour.x][neighbour.y] )
431 ) {
432 const float source_light =
433 std::min( natural_light, lm[neighbour.x][neighbour.y].max() );
435 update_light_quadrants( lm[p.x][p.y], source_light, quadrant::default_ );
436 apply_directional_light( p, dir_d[i], source_light );
437 } else {
438 update_light_quadrants( lm[p.x][p.y], source_light, dir_quadrants[i][0] );
439 update_light_quadrants( lm[p.x][p.y], source_light, dir_quadrants[i][1] );
440 }
441 }
442 }
443 }
444
445 if( cur_submap->get_lum( { sx, sy } ) && has_items( p ) ) {
446 auto items = i_at( p );
447 add_light_from_items( p, items.begin(), items.end() );
448 }
449
450 const ter_id terrain = cur_submap->get_ter( { sx, sy } );
451 if( terrain->light_emitted > 0 ) {
452 add_light_source( p, terrain->light_emitted );
453 }
454 const furn_id furniture = cur_submap->get_furn( {sx, sy } );
455 if( furniture->light_emitted > 0 ) {
456 add_light_source( p, furniture->light_emitted );
457 }
458
459 for( auto &fld : cur_submap->get_field( { sx, sy } ) ) {
460 const field_entry *cur = &fld.second;
461 const int light_emitted = cur->light_emitted();
462 if( light_emitted > 0 ) {
463 add_light_source( p, light_emitted );
464 }
465 const float light_override = cur->local_light_override();
466 if( light_override >= 0.0 ) {
467 lm_override.push_back( std::pair<tripoint, float>( p, light_override ) );
468 }
469 }
470 }
471 }
472 }
473 }
474
475 for( monster &critter : g->all_monsters() ) {
476 if( critter.is_hallucination() ) {
477 continue;
478 }
479 const tripoint &mp = critter.pos();
480 if( inbounds( mp ) ) {
481 if( critter.has_effect( effect_onfire ) ) {
482 apply_light_source( mp, 8 );
483 }
484 // TODO: [lightmap] Attach natural light brightness to creatures
485 // TODO: [lightmap] Allow creatures to have light attacks (i.e.: eyebot)
486 // TODO: [lightmap] Allow creatures to have facing and arc lights
487 if( critter.type->luminance > 0 ) {
488 apply_light_source( mp, critter.type->luminance );
489 }
490 }
491 }
492
493 // Apply any vehicle light sources
494 VehicleList vehs = get_vehicles();
495 for( auto &vv : vehs ) {
496 vehicle *v = vv.v;
497
498 auto lights = v->lights( true );
499
500 float veh_luminance = 0.0;
501 float iteration = 1.0;
502
503 for( const auto pt : lights ) {
504 const auto &vp = pt->info();
505 if( vp.has_flag( VPFLAG_CONE_LIGHT ) ||
506 vp.has_flag( VPFLAG_WIDE_CONE_LIGHT ) ) {
507 veh_luminance += vp.bonus / iteration;
508 iteration = iteration * 1.1;
509 }
510 }
511
512 for( const auto pt : lights ) {
513 const auto &vp = pt->info();
514 tripoint src = v->global_part_pos3( *pt );
515
516 if( !inbounds( src ) ) {
517 continue;
518 }
519
520 if( vp.has_flag( VPFLAG_CONE_LIGHT ) ) {
521 if( veh_luminance > lit_level::LIT ) {
522 add_light_source( src, M_SQRT2 ); // Add a little surrounding light
523 apply_light_arc( src, v->face.dir() + pt->direction, veh_luminance,
524 45_degrees );
525 }
526
527 } else if( vp.has_flag( VPFLAG_WIDE_CONE_LIGHT ) ) {
528 if( veh_luminance > lit_level::LIT ) {
529 add_light_source( src, M_SQRT2 ); // Add a little surrounding light
530 apply_light_arc( src, v->face.dir() + pt->direction, veh_luminance,
531 90_degrees );
532 }
533
534 } else if( vp.has_flag( VPFLAG_HALF_CIRCLE_LIGHT ) ) {
535 add_light_source( src, M_SQRT2 ); // Add a little surrounding light
536 apply_light_arc( src, v->face.dir() + pt->direction, vp.bonus, 180_degrees );
537
538 } else if( vp.has_flag( VPFLAG_CIRCLE_LIGHT ) ) {
539 const bool odd_turn = calendar::once_every( 2_turns );
540 if( ( odd_turn && vp.has_flag( VPFLAG_ODDTURN ) ) ||
541 ( !odd_turn && vp.has_flag( VPFLAG_EVENTURN ) ) ||
542 ( !( vp.has_flag( VPFLAG_EVENTURN ) || vp.has_flag( VPFLAG_ODDTURN ) ) ) ) {
543
544 add_light_source( src, vp.bonus );
545 }
546
547 } else {
548 add_light_source( src, vp.bonus );
549 }
550 }
551
552 for( const vpart_reference &vp : v->get_all_parts() ) {
553 const size_t p = vp.part_index();
554 const tripoint pp = vp.pos();
555 if( !inbounds( pp ) ) {
556 continue;
557 }
558 if( vp.has_feature( VPFLAG_CARGO ) && !vp.has_feature( "COVERED" ) ) {
559 add_light_from_items( pp, v->get_items( static_cast<int>( p ) ).begin(),
560 v->get_items( static_cast<int>( p ) ).end() );
561 }
562 }
563 }
564
565 /* Now that we have position and intensity of all bulk light sources, apply_ them
566 This may seem like extra work, but take a 12x12 raging inferno:
567 unbuffered: (12^2)*(160*4) = apply_light_ray x 92160
568 buffered: (12*4)*(160) = apply_light_ray x 7680
569 */
570 const tripoint cache_start( 0, 0, zlev );
571 const tripoint cache_end( LIGHTMAP_CACHE_X, LIGHTMAP_CACHE_Y, zlev );
572 for( const tripoint &p : points_in_rectangle( cache_start, cache_end ) ) {
573 if( light_source_buffer[p.x][p.y] > 0.0 ) {
574 apply_light_source( p, light_source_buffer[p.x][p.y] );
575 }
576 }
577 for( const std::pair<tripoint, float> &elem : lm_override ) {
578 lm[elem.first.x][elem.first.y].fill( elem.second );
579 }
580}
float light_emitted() const
Definition: field.cpp:69
float local_light_override() const
Definition: field.cpp:74
float light_transparency(const tripoint &p) const
Definition: lightmap.cpp:629
void apply_directional_light(const tripoint &p, int direction, float luminance)
Definition: lightmap.cpp:1439
void build_sunlight_cache(int pzlev)
Definition: lightmap.cpp:218
void add_light_from_items(const tripoint &p, item_stack::iterator begin, item_stack::iterator end)
Definition: lightmap.cpp:63
void apply_character_light(Character &p)
Definition: lightmap.cpp:196
Definition: npc.h:781
units::angle dir() const
Definition: tileray.cpp:74
std::vector< vehicle_part * > lights(bool active=false)
Get all vehicle lights (excluding any that are destroyed)
Definition: vehicle.cpp:4465
vehicle_stack get_items(int part) const
Definition: vehicle.cpp:5291
bool once_every(const time_duration &event_frequency)
Predicate to handle rate-limiting.
Definition: calendar.cpp:490
@ VPFLAG_CONE_LIGHT
Definition: veh_type.h:35
@ VPFLAG_CIRCLE_LIGHT
Definition: veh_type.h:38
@ VPFLAG_CARGO
Definition: veh_type.h:62
@ VPFLAG_EVENTURN
Definition: veh_type.h:33
@ VPFLAG_WIDE_CONE_LIGHT
Definition: veh_type.h:36
@ VPFLAG_ODDTURN
Definition: veh_type.h:34
@ VPFLAG_HALF_CIRCLE_LIGHT
Definition: veh_type.h:37

References add_light_from_items(), add_light_source(), apply_character_light(), apply_directional_light(), apply_light_arc(), apply_light_source(), item_stack::begin(), build_sunlight_cache(), clamp(), default_, tileray::dir(), effect_onfire, item_stack::end(), vehicle::face, level_cache::floor_cache, furniture, g, vehicle::get_all_parts(), get_cache(), vehicle::get_items(), get_player_character(), get_submap_at_grid(), get_vehicles(), vehicle::global_part_pos3(), has_items(), i_at(), inbounds(), field_entry::light_emitted(), light_transparency(), LIGHT_TRANSPARENCY_SOLID, lightmap_boundaries, LIGHTMAP_CACHE_X, LIGHTMAP_CACHE_Y, vehicle::lights(), LIT, field_entry::local_light_override(), M_SQRT2, my_MAPSIZE, NE, NW, calendar::once_every(), OVERMAP_DEPTH, points_in_rectangle(), SE, SEEX, SEEY, coords::sm, SW, sx, sy, terrain, update_light_quadrants(), VPFLAG_CARGO, VPFLAG_CIRCLE_LIGHT, VPFLAG_CONE_LIGHT, VPFLAG_EVENTURN, VPFLAG_HALF_CIRCLE_LIGHT, VPFLAG_ODDTURN, VPFLAG_WIDE_CONE_LIGHT, point::x, tripoint::x, tripoint::xy(), point::y, and tripoint::y.

Referenced by build_map_cache().

◆ get_abs_sub()

◆ get_active_items_in_radius() [1/2]

std::list< item_location > map::get_active_items_in_radius ( const tripoint center,
int  radius 
) const

Definition at line 8448 of file map.cpp.

8450{
8452}
std::list< item_location > get_active_items_in_radius(const tripoint &center, int radius) const
Definition: map.cpp:8448

References center, get_active_items_in_radius(), and none.

Referenced by npc::find_corpse_to_pulp(), npc::find_dangerous_explosives(), and get_active_items_in_radius().

◆ get_active_items_in_radius() [2/2]

std::list< item_location > map::get_active_items_in_radius ( const tripoint center,
int  radius,
special_item_type  type 
) const

Definition at line 8454 of file map.cpp.

8456{
8457 std::list<item_location> result;
8458
8459 const point minp( center.xy() + point( -radius, -radius ) );
8460 const point maxp( center.xy() + point( radius, radius ) );
8461
8462 const point ming( std::max( minp.x / SEEX, 0 ),
8463 std::max( minp.y / SEEY, 0 ) );
8464 const point maxg( std::min( maxp.x / SEEX, my_MAPSIZE - 1 ),
8465 std::min( maxp.y / SEEY, my_MAPSIZE - 1 ) );
8466
8467 for( const tripoint &abs_submap_loc : submaps_with_active_items ) {
8468 const tripoint submap_loc{ -abs_sub.xy() + abs_submap_loc };
8469 if( submap_loc.x < ming.x || submap_loc.y < ming.y ||
8470 submap_loc.x > maxg.x || submap_loc.y > maxg.y ) {
8471 continue;
8472 }
8473 const point sm_offset( submap_loc.x * SEEX, submap_loc.y * SEEY );
8474
8475 submap *sm = get_submap_at_grid( submap_loc );
8476 std::vector<item_reference> items = type == special_item_type::none ? sm->active_items.get() :
8477 sm->active_items.get_special( type );
8478 for( const auto &elem : items ) {
8479 const tripoint pos( sm_offset + elem.location, submap_loc.z );
8480
8481 if( rl_dist( pos, center ) > radius ) {
8482 continue;
8483 }
8484
8485 if( elem.item_ref ) {
8486 result.emplace_back( map_cursor( pos ), elem.item_ref.get() );
8487 }
8488 }
8489 }
8490
8491 return result;
8492}

References abs_sub, center, get_submap_at_grid(), my_MAPSIZE, none, rl_dist(), SEEX, SEEY, coords::sm, submaps_with_active_items, type, point::x, tripoint::xy(), and point::y.

◆ get_cache()

◆ get_cache_ref()

◆ get_creatures_in_radius()

std::list< Creature * > map::get_creatures_in_radius ( const tripoint center,
size_t  radius,
size_t  radiusz = 0 
)

returns creatures in specified radius

Definition at line 8508 of file map.cpp.

8510{
8511 std::list<Creature *> creatures;
8512 for( const auto &loc : points_in_radius( center, radius, radiusz ) ) {
8513 Creature *tmp_critter = g->critter_at( loc );
8514 if( tmp_critter != nullptr ) {
8515 creatures.push_back( tmp_critter );
8516 }
8517
8518 }
8519 return creatures;
8520}

References center, g, and points_in_radius().

◆ get_dir_circle()

std::vector< tripoint > map::get_dir_circle ( const tripoint f,
const tripoint t 
) const

Calculate next search points surrounding the current position.

Points closer to the target come first. This method leads to straighter lines and prevents weird looking movements away from the target.

Definition at line 6445 of file map.cpp.

6446{
6447 std::vector<tripoint> circle;
6448 circle.resize( 8 );
6449
6450 // The line below can be crazy expensive - we only take the FIRST point of it
6451 const std::vector<tripoint> line = line_to( f, t, 0, 0 );
6452 const std::vector<tripoint> spiral = closest_points_first( f, 1 );
6453 const std::vector<int> pos_index {1, 2, 4, 6, 8, 7, 5, 3};
6454
6455 // All possible constellations (closest_points_first goes clockwise)
6456 // 753 531 312 124 246 468 687 875
6457 // 8 1 7 2 5 4 3 6 1 8 2 7 4 5 6 3
6458 // 642 864 786 578 357 135 213 421
6459
6460 size_t pos_offset = 0;
6461 for( size_t i = 1; i < spiral.size(); i++ ) {
6462 if( spiral[i] == line[0] ) {
6463 pos_offset = i - 1;
6464 break;
6465 }
6466 }
6467
6468 for( size_t i = 1; i < spiral.size(); i++ ) {
6469 if( pos_offset >= pos_index.size() ) {
6470 pos_offset = 0;
6471 }
6472
6473 circle[pos_index[pos_offset++] - 1] = spiral[i];
6474 }
6475
6476 return circle;
6477}
void circle(map *m, const ter_id &type, double x, double y, double rad)
Definition: mapgen.cpp:6495

References circle(), closest_points_first(), line(), and line_to().

Referenced by npc::move_to().

◆ get_field() [1/2]

field & map::get_field ( const tripoint p)
private

Definition at line 8280 of file map.cpp.

8281{
8282 return field_at( p );
8283}

References field_at().

◆ get_field() [2/2]

field_entry * map::get_field ( const tripoint p,
const field_type_id type 
)

◆ get_field_age()

time_duration map::get_field_age ( const tripoint p,
const field_type_id type 
) const

Get the age of a field entry (field_entry::age), if there is no field of that type, returns -1_turns.

Definition at line 5351 of file map.cpp.

5352{
5353 auto field_ptr = field_at( p ).find_field( type );
5354 return field_ptr == nullptr ? -1_turns : field_ptr->get_field_age();
5355}

References field_at(), field::find_field(), field_entry::get_field_age(), and type.

Referenced by game::grabbed_furn_move(), try_fuel_fire(), and game::walk_move().

◆ get_field_intensity()

int map::get_field_intensity ( const tripoint p,
const field_type_id type 
) const

Get the intensity of a field entry (field_entry::intensity), if there is no field of that type, returns 0.

Definition at line 5357 of file map.cpp.

5358{
5359 auto field_ptr = field_at( p ).find_field( type );
5360 return ( field_ptr == nullptr ? 0 : field_ptr->get_field_intensity() );
5361}

References field_at(), field::find_field(), and type.

Referenced by Character::base_comfort_value(), game::grabbed_furn_move(), is_flammable(), propagate_field(), fungal_effects::spread_fungus_one_tile(), and game::walk_move().

◆ get_furn_field_locations()

const std::vector< tripoint > & map::get_furn_field_locations ( ) const

Definition at line 7604 of file map.cpp.

7605{
7606 return field_furn_locs;
7607}

References field_furn_locs.

Referenced by game::do_turn().

◆ get_furn_transforms_into()

furn_id map::get_furn_transforms_into ( const tripoint p) const

Definition at line 1607 of file map.cpp.

1608{
1609 return furn( p ).obj().transforms_into.id();
1610}
furn_str_id transforms_into
Definition: mapdata.h:493

References furn(), string_id< T >::id(), int_id< T >::obj(), and furn_t::transforms_into.

◆ get_harvest()

const harvest_id & map::get_harvest ( const tripoint p) const

Returns the full harvest list, for spawning.

Definition at line 1559 of file map.cpp.

1560{
1561 const auto furn_here = furn( pos );
1562 if( furn_here->examine != iexamine::none ) {
1563 // Note: if furniture can be examined, the terrain can NOT (until furniture is removed)
1564 if( furn_here->has_flag( TFLAG_HARVESTED ) ) {
1565 return harvest_id::NULL_ID();
1566 }
1567
1568 return furn_here->get_harvest();
1569 }
1570
1571 const auto ter_here = ter( pos );
1572 if( ter_here->has_flag( TFLAG_HARVESTED ) ) {
1573 return harvest_id::NULL_ID();
1574 }
1575
1576 return ter_here->get_harvest();
1577}
static const string_id< harvest_list > & NULL_ID()
Returns a null id whose string_id<T>::is_null() must always return true.
@ TFLAG_HARVESTED
Definition: mapdata.h:303

References furn(), iexamine::none(), string_id< harvest_list >::NULL_ID(), wrapped_vehicle::pos, ter(), and TFLAG_HARVESTED.

Referenced by harvest_common(), and is_harvestable().

◆ get_harvest_names()

const std::set< std::string > & map::get_harvest_names ( const tripoint p) const

Returns names of the items that would be dropped.

Definition at line 1579 of file map.cpp.

1580{
1581 static const std::set<std::string> null_harvest_names = {};
1582 const auto furn_here = furn( pos );
1583 if( furn_here->examine != iexamine::none ) {
1584 if( furn_here->has_flag( TFLAG_HARVESTED ) ) {
1585 return null_harvest_names;
1586 }
1587
1588 return furn_here->get_harvest_names();
1589 }
1590
1591 const auto ter_here = ter( pos );
1592 if( ter_here->has_flag( TFLAG_HARVESTED ) ) {
1593 return null_harvest_names;
1594 }
1595
1596 return ter_here->get_harvest_names();
1597}

References furn(), iexamine::none(), wrapped_vehicle::pos, ter(), and TFLAG_HARVESTED.

Referenced by npc::find_item().

◆ get_known_connections()

uint8_t map::get_known_connections ( const tripoint p,
int  connect_group,
const std::map< tripoint, ter_id > &  override = {} 
) const

Definition at line 1505 of file map.cpp.

1507{
1508 auto &ch = access_cache( p.z );
1509 uint8_t val = 0;
1510 std::function<bool( const tripoint & )> is_memorized;
1511#ifdef TILES
1512 if( use_tiles ) {
1513 is_memorized =
1514 [&]( const tripoint & q ) {
1515 return !g->u.get_memorized_tile( getabs( q ) ).tile.empty();
1516 };
1517 } else {
1518#endif
1519 is_memorized =
1520 [&]( const tripoint & q ) {
1521 return g->u.get_memorized_symbol( getabs( q ) );
1522 };
1523#ifdef TILES
1524 }
1525#endif
1526
1527 const bool overridden = override.find( p ) != override.end();
1528 const bool is_transparent = ch.transparency_cache[p.x][p.y] > LIGHT_TRANSPARENCY_SOLID;
1529
1530 // populate connection information
1531 for( int i = 0; i < 4; ++i ) {
1532 tripoint neighbour = p + offsets[i];
1533 if( !inbounds( neighbour ) ) {
1534 continue;
1535 }
1536 const auto neighbour_override = override.find( neighbour );
1537 const bool neighbour_overridden = neighbour_override != override.end();
1538 // if there's some non-memory terrain to show at the neighboring tile
1539 const bool may_connect = neighbour_overridden ||
1540 get_visibility( ch.visibility_cache[neighbour.x][neighbour.y],
1542 // or if an actual center tile is transparent or next to a memorized tile
1543 ( !overridden && ( is_transparent || is_memorized( neighbour ) ) );
1544 if( may_connect ) {
1545 const ter_t &neighbour_terrain = neighbour_overridden ?
1546 neighbour_override->second.obj() : ter( neighbour ).obj();
1547 if( neighbour_terrain.connects_to( connect_group ) ) {
1548 val += 1 << i;
1549 }
1550 }
1551 }
1552
1553 return val;
1554}
bool use_tiles
Use tiles for display.
bool is_transparent(const tripoint &p) const
Returns whether the tile at p is transparent(you can look past it).
Definition: lightmap.cpp:624
level_cache & access_cache(int zlev)
Definition: map.cpp:8522
static constexpr std::array< point, 4 > offsets
Definition: point.h:371
bool connects_to(int test_connect_group) const
Definition: mapdata.h:431

References access_cache(), map_data_common_t::connects_to(), g, get_visibility(), get_visibility_variables_cache(), getabs(), inbounds(), is_transparent(), LIGHT_TRANSPARENCY_SOLID, int_id< T >::obj(), offsets, ter(), use_tiles, VIS_CLEAR, tripoint::x, tripoint::y, and tripoint::z.

Referenced by determine_wall_corner().

◆ get_neighbors()

std::array< std::pair< tripoint, maptile >, 8 > map::get_neighbors ( const tripoint p)
private

Definition at line 190 of file map_field.cpp.

191{
192 // Find out which edges are in the bubble
193 // Where possible, do just one bounds check for all the neighbors
194 const bool west = p.x > 0;
195 const bool north = p.y > 0;
196 const bool east = p.x < SEEX * my_MAPSIZE - 1;
197 const bool south = p.y < SEEY * my_MAPSIZE - 1;
198 return std::array< std::pair<tripoint, maptile>, 8 > { {
199 maptile_has_bounds( p + eight_horizontal_neighbors[0], west &&north ),
201 maptile_has_bounds( p + eight_horizontal_neighbors[2], east &&north ),
204 maptile_has_bounds( p + eight_horizontal_neighbors[5], west &&south ),
206 maptile_has_bounds( p + eight_horizontal_neighbors[7], east &&south ),
207 }
208 };
209}
std::pair< tripoint, maptile > maptile_has_bounds(const tripoint &p, bool bounds_checked)
Definition: map_field.cpp:180
static const std::array< tripoint, 8 > eight_horizontal_neighbors
Definition: point.h:389

References eight_horizontal_neighbors, maptile_has_bounds(), my_MAPSIZE, SEEX, SEEY, tripoint::x, and tripoint::y.

Referenced by process_fields_in_submap(), and spread_gas().

◆ get_nonant() [1/2]

size_t map::get_nonant ( const point gridp) const
inlineprotected

Definition at line 1851 of file map.h.

1851 {
1852 return get_nonant( { gridp, abs_sub.z } );
1853 }

References abs_sub, get_nonant(), and tripoint::z.

◆ get_nonant() [2/2]

size_t map::get_nonant ( const tripoint gridp) const
protected

Get the index of a submap pointer in the grid given by grid coordinates.

The grid coordinates must be valid: 0 <= x < my_MAPSIZE, same for y. Version with z-levels checks for z between -OVERMAP_DEPTH and OVERMAP_HEIGHT

Definition at line 8136 of file map.cpp.

8137{
8138 // There used to be a bounds check here
8139 // But this function is called a lot, so push it up if needed
8140 if( zlevels ) {
8141 const int indexz = gridp.z + OVERMAP_HEIGHT; // Can't be lower than 0
8142 return indexz + ( gridp.x + gridp.y * my_MAPSIZE ) * OVERMAP_LAYERS;
8143 } else {
8144 return gridp.x + gridp.y * my_MAPSIZE;
8145 }
8146}

References my_MAPSIZE, OVERMAP_HEIGHT, OVERMAP_LAYERS, tripoint::x, tripoint::y, tripoint::z, and zlevels.

Referenced by copy_grid(), fake_map::fake_map(), generate(), get_nonant(), get_submap_at_grid(), loadn(), and saven().

◆ get_pathfinding_cache()

pathfinding_cache & map::get_pathfinding_cache ( int  zlev) const
private

Definition at line 8570 of file map.cpp.

8571{
8572 return *pathfinding_caches[zlev + OVERMAP_DEPTH];
8573}

References OVERMAP_DEPTH, and pathfinding_caches.

Referenced by get_pathfinding_cache_ref(), set_pathfinding_cache_dirty(), and update_pathfinding_cache().

◆ get_pathfinding_cache_ref()

const pathfinding_cache & map::get_pathfinding_cache_ref ( int  zlev) const

Definition at line 8582 of file map.cpp.

8583{
8584 if( !inbounds_z( zlev ) ) {
8585 debugmsg( "Tried to get pathfinding cache for out of bounds z-level %d", zlev );
8587 }
8588 auto &cache = get_pathfinding_cache( zlev );
8589 if( cache.dirty ) {
8591 }
8592
8593 return cache;
8594}
void update_pathfinding_cache(int zlev) const
Definition: map.cpp:8596
bool inbounds_z(const int z) const
Definition: map.h:1643
pathfinding_cache & get_pathfinding_cache(int zlev) const
Definition: map.cpp:8570

References debugmsg, get_pathfinding_cache(), inbounds_z(), OVERMAP_DEPTH, pathfinding_caches, and update_pathfinding_cache().

Referenced by route(), and vertical_move_destination().

◆ get_radiation()

int map::get_radiation ( const tripoint p) const

Definition at line 4013 of file map.cpp.

4014{
4015 if( !inbounds( p ) ) {
4016 return 0;
4017 }
4018
4019 point l;
4020 submap *const current_submap = get_submap_at( p, l );
4021
4022 return current_submap->get_radiation( l );
4023}

References submap::get_radiation(), get_submap_at(), and inbounds().

Referenced by computer_session::action_geiger(), computer_session::action_irradiator(), check_art_charge_req(), editmap::draw_main_ui_overlay(), and rad_scorch().

◆ get_roof()

ter_id map::get_roof ( const tripoint p,
bool  allow_air 
) const
private

Definition at line 3089 of file map.cpp.

3090{
3091 // This function should not be called from the 2D mode
3092 // Just use t_dirt instead
3093 assert( zlevels );
3094
3095 if( p.z <= -OVERMAP_DEPTH ) {
3096 // Could be magma/"void" instead
3097 return t_rock_floor;
3098 }
3099
3100 const auto &ter_there = ter( p ).obj();
3101 const auto &roof = ter_there.roof;
3102 if( !roof ) {
3103 // No roof
3104 if( !allow_air ) {
3105 // TODO: Biomes? By setting? Forbid and treat as bug?
3106 if( p.z < 0 ) {
3107 return t_rock_floor_no_roof;
3108 }
3109
3110 return t_dirt;
3111 }
3112
3113 return t_open_air;
3114 }
3115
3116 ter_id new_ter = roof.id();
3117 if( new_ter == t_null ) {
3118 debugmsg( "map::get_new_floor: %d,%d,%d has invalid roof type %s",
3119 p.x, p.y, p.z, roof.c_str() );
3120 return t_dirt;
3121 }
3122
3123 if( p.z == -1 && new_ter == t_rock_floor ) {
3124 // HACK: A hack to work around not having a "solid earth" tile
3125 new_ter = t_dirt;
3126 }
3127
3128 return new_ter;
3129}
static const ter_str_id t_rock_floor_no_roof("t_rock_floor_no_roof")

References debugmsg, int_id< T >::id(), int_id< T >::obj(), OVERMAP_DEPTH, ter_t::roof, t_dirt, t_null, t_open_air, t_rock_floor, t_rock_floor_no_roof, ter(), tripoint::x, tripoint::y, tripoint::z, and zlevels.

Referenced by bash_ter_furn(), and bash_ter_success().

◆ get_signage()

std::string map::get_signage ( const tripoint p) const

Definition at line 3979 of file map.cpp.

3980{
3981 if( !inbounds( p ) ) {
3982 return "";
3983 }
3984
3985 point l;
3986 submap *const current_submap = get_submap_at( p, l );
3987
3988 return current_submap->get_signage( l );
3989}
std::string get_signage(const point &p) const
Definition: submap.cpp:126

References submap::get_signage(), get_submap_at(), and inbounds().

Referenced by game::extended_description(), game::place_player(), game::print_terrain_info(), and iexamine::sign().

◆ get_submap_at() [1/4]

submap * map::get_submap_at ( const point p) const
inlineprivate

Definition at line 1823 of file map.h.

1823 {
1824 return get_submap_at( tripoint( p, abs_sub.z ) );
1825 }

References abs_sub, get_submap_at(), and tripoint::z.

◆ get_submap_at() [2/4]

submap * map::get_submap_at ( const point p,
point offset_p 
) const
inlineprivate

Definition at line 1832 of file map.h.

1832 {
1833 return get_submap_at( { p, abs_sub.z }, offset_p );
1834 }

References abs_sub, get_submap_at(), and tripoint::z.

◆ get_submap_at() [3/4]

◆ get_submap_at() [4/4]

submap * map::get_submap_at ( const tripoint p,
point offset_p 
) const
private

Get the submap pointer containing the specified position within the reality bubble.

The same as other get_submap_at, (p) must be valid (inbounds). Also writes the position within the submap to offset_p

Definition at line 8124 of file map.cpp.

8125{
8126 offset_p.x = p.x % SEEX;
8127 offset_p.y = p.y % SEEY;
8128 return get_submap_at( p );
8129}

References get_submap_at(), SEEX, SEEY, point::x, tripoint::x, point::y, and tripoint::y.

◆ get_submap_at_grid() [1/2]

◆ get_submap_at_grid() [2/2]

submap * map::get_submap_at_grid ( const tripoint gridp) const
private

Definition at line 8131 of file map.cpp.

8132{
8133 return getsubmap( get_nonant( gridp ) );
8134}

References get_nonant(), and getsubmap().

◆ get_submaps_with_active_items()

const std::set< tripoint > & map::get_submaps_with_active_items ( ) const
inline

Definition at line 2024 of file map.h.

2024 {
2026 }

References submaps_with_active_items.

◆ get_temperature()

int map::get_temperature ( const tripoint p) const

Definition at line 4050 of file map.cpp.

4051{
4052 if( !inbounds( p ) ) {
4053 return 0;
4054 }
4055
4056 return get_submap_at( p )->get_temperature();
4057}
int get_temperature() const
Definition: submap.h:194

References get_submap_at(), submap::get_temperature(), and inbounds().

◆ get_ter_transforms_into()

ter_id map::get_ter_transforms_into ( const tripoint p) const

Definition at line 1602 of file map.cpp.

1603{
1604 return ter( p ).obj().transforms_into.id();
1605}
ter_str_id transforms_into
Definition: mapdata.h:463

References string_id< T >::id(), int_id< T >::obj(), ter(), and ter_t::transforms_into.

Referenced by iexamine::harvest_ter(), iexamine::harvest_ter_nectar(), and iexamine::tree_hickory().

◆ get_vehicle_zones()

std::vector< zone_data * > map::get_vehicle_zones ( int  zlev)

Definition at line 934 of file map.cpp.

935{
936 std::vector<zone_data *> veh_zones;
937 bool rebuild = false;
938 for( auto veh : get_cache( zlev ).zone_vehicles ) {
939 if( veh->refresh_zones() ) {
940 rebuild = true;
941 }
942 for( auto &zone : veh->loot_zones ) {
943 veh_zones.emplace_back( &zone.second );
944 }
945 }
946 if( rebuild ) {
948 }
949 return veh_zones;
950}
static zone_manager & get_manager()
Definition: clzones.cpp:125
void cache_vzones()
Definition: clzones.cpp:624

References zone_manager::cache_vzones(), get_cache(), and zone_manager::get_manager().

Referenced by zone_manager::cache_vzones(), zone_manager::get_bottom_zone(), zone_manager::get_zone_at(), and zone_manager::get_zones().

◆ get_vehicles() [1/2]

◆ get_vehicles() [2/2]

VehicleList map::get_vehicles ( const tripoint start,
const tripoint end 
)

Definition at line 975 of file map.cpp.

976{
977 const int chunk_sx = std::max( 0, ( start.x / SEEX ) - 1 );
978 const int chunk_ex = std::min( my_MAPSIZE - 1, ( end.x / SEEX ) + 1 );
979 const int chunk_sy = std::max( 0, ( start.y / SEEY ) - 1 );
980 const int chunk_ey = std::min( my_MAPSIZE - 1, ( end.y / SEEY ) + 1 );
981 const int chunk_sz = start.z;
982 const int chunk_ez = end.z;
983 VehicleList vehs;
984
985 for( int cx = chunk_sx; cx <= chunk_ex; ++cx ) {
986 for( int cy = chunk_sy; cy <= chunk_ey; ++cy ) {
987 for( int cz = chunk_sz; cz <= chunk_ez; ++cz ) {
988 submap *current_submap = get_submap_at_grid( { cx, cy, cz } );
989 for( const auto &elem : current_submap->vehicles ) {
990 // Ensure the vehicle z-position is correct
991 elem->sm_pos.z = cz;
993 w.v = elem.get();
994 w.pos = w.v->global_pos3();
995 vehs.push_back( w );
996 }
997 }
998 }
999 }
1000
1001 return vehs;
1002}
tripoint pos
Definition: map.h:81
vehicle * v
Definition: map.h:82

References get_submap_at_grid(), vehicle::global_pos3(), my_MAPSIZE, wrapped_vehicle::pos, SEEX, SEEY, wrapped_vehicle::v, submap::vehicles, tripoint::x, tripoint::y, and tripoint::z.

◆ get_visibility()

visibility_type map::get_visibility ( lit_level  ll,
const visibility_variables cache 
) const

Definition at line 5620 of file map.cpp.

5622{
5623 switch( ll ) {
5624 case lit_level::DARK:
5625 // can't see this square at all
5626 if( cache.u_is_boomered ) {
5627 return VIS_BOOMER_DARK;
5628 } else {
5629 return VIS_DARK;
5630 }
5632 // can only tell that this square is bright
5633 if( cache.u_is_boomered ) {
5634 return VIS_BOOMER;
5635 } else {
5636 return VIS_LIT;
5637 }
5638
5639 case lit_level::LOW:
5640 // low light, square visible in monochrome
5641 case lit_level::LIT:
5642 // normal light
5643 case lit_level::BRIGHT:
5644 // bright light
5645 return VIS_CLEAR;
5646 case lit_level::BLANK:
5648 return VIS_HIDDEN;
5649 }
5650 return VIS_HIDDEN;
5651}
bool u_is_boomered
Definition: map.h:120

References BLANK, BRIGHT, BRIGHT_ONLY, DARK, LIT, LOW, MEMORIZED, visibility_variables::u_is_boomered, VIS_BOOMER, VIS_BOOMER_DARK, VIS_CLEAR, VIS_DARK, VIS_HIDDEN, and VIS_LIT.

Referenced by draw(), game::draw_look_around_cursor(), generate_weather_anim_frame(), get_known_connections(), and game::print_all_tile_info().

◆ get_visibility_variables_cache()

const visibility_variables & map::get_visibility_variables_cache ( ) const

Definition at line 5615 of file map.cpp.

5616{
5618}
visibility_variables visibility_variables_cache
Definition: map.h:2003

References visibility_variables_cache.

Referenced by draw(), generate_weather_anim_frame(), get_known_connections(), game::look_around(), live_view::show(), and editmap::update_view_with_help().

◆ get_wind_blockers()

std::tuple< maptile, maptile, maptile > map::get_wind_blockers ( const int &  winddirection,
const tripoint pos 
)

Definition at line 1891 of file map_field.cpp.

1893{
1894 static const std::array<std::pair<int, std::tuple< point, point, point >>, 9> outputs = {{
1895 { 330, std::make_tuple( point_east, point_north_east, point_south_east ) },
1896 { 301, std::make_tuple( point_south_east, point_east, point_south ) },
1897 { 240, std::make_tuple( point_south, point_south_west, point_south_east ) },
1898 { 211, std::make_tuple( point_south_west, point_west, point_south ) },
1899 { 150, std::make_tuple( point_west, point_north_west, point_south_west ) },
1900 { 121, std::make_tuple( point_north_west, point_north, point_west ) },
1901 { 60, std::make_tuple( point_north, point_north_west, point_north_east ) },
1902 { 31, std::make_tuple( point_north_east, point_east, point_north ) },
1903 { 0, std::make_tuple( point_east, point_north_east, point_south_east ) }
1904 }
1905 };
1906
1907 tripoint removepoint;
1908 tripoint removepoint2;
1909 tripoint removepoint3;
1910 for( const std::pair<int, std::tuple< point, point, point >> &val : outputs ) {
1911 if( winddirection >= val.first ) {
1912 removepoint = pos + std::get<0>( val.second );
1913 removepoint2 = pos + std::get<1>( val.second );
1914 removepoint3 = pos + std::get<2>( val.second );
1915 break;
1916 }
1917 }
1918
1919 const maptile remove_tile = maptile_at( removepoint );
1920 const maptile remove_tile2 = maptile_at( removepoint2 );
1921 const maptile remove_tile3 = maptile_at( removepoint3 );
1922 return std::make_tuple( remove_tile, remove_tile2, remove_tile3 );
1923}

References maptile_at(), point_east, point_north, point_north_east, point_north_west, point_south, point_south_east, point_south_west, and point_west.

Referenced by spread_gas().

◆ getabs() [1/2]

point map::getabs ( const point p) const
inline

Definition at line 1628 of file map.h.

1628 {
1629 return getabs( tripoint( p, abs_sub.z ) ).xy();
1630 }

References abs_sub, getabs(), tripoint::xy(), and tripoint::z.

◆ getabs() [2/2]

tripoint map::getabs ( const tripoint p) const

Translates local (to this map) coordinates of a square to global absolute coordinates.

Coordinates is in the system that is used by the ter/furn/i_at functions. Output is in the same scale, but in global system.

Definition at line 8074 of file map.cpp.

8075{
8076 return sm_to_ms_copy( abs_sub.xy() ) + p;
8077}

References abs_sub, sm_to_ms_copy(), and tripoint::xy().

Referenced by activity_on_turn_move_loot(), add_basecamp_storage_to_loot_zone_list(), add_item(), Character::add_known_trap(), jmapgen_zone::apply(), are_requirements_nearby(), game::autopilot_vehicles(), talk_function::basecamp_mission(), bash_ter_furn(), iexamine::bulletin_board(), butcher_corpse_activity(), can_do_activity_there(), iexamine::cardreader(), vehicle::autodrive_controller::check_drivable(), game::check_near_zone(), game::check_zone(), chop_plank_activity(), chop_tree_activity(), complete_construction(), construction_activity(), game::control_vehicle(), activity_handlers::repair_activity_hack::anonymous_namespace{activity_handlers.cpp}::discharge_real_power_source(), npc::do_pulp(), construct::done_digormine_stair(), construct::done_mine_upstair(), draw_maptile(), editmap::edit_mapgen(), iexamine::elevator(), fill_funnels(), find_auto_consume(), game::find_or_make_stairs(), find_refuel_spot_zone(), find_valid_teleporters_omt(), activity_handlers::forage_finish(), inventory::form_from_map(), furn_set(), generic_multi_activity_check_requirement(), generic_multi_activity_do(), generic_multi_activity_handler(), generic_multi_activity_locations(), activity_handlers::repair_activity_hack::anonymous_namespace{activity_handlers.cpp}::get_fake_tool(), get_known_connections(), zone_manager::get_point_set_loot(), getabs(), Character::global_square_location(), npc::go_to_omt_destination(), good_fishing_spot(), game::grabbed_furn_move(), grow_plant(), npc::guard_current_pos(), Character::knows_trap(), mine_activity(), npc::move(), perform_zone_activity_turn(), place_construction(), game::place_player(), basecamp::place_results(), game::place_vehicle_nearby(), iexamine::plant_seed(), game::pre_print_all_tile_info(), sounds::process_sounds(), plot_options::query_seed(), npc::reach_omt_destination(), remove_submap_turrets(), requirements_map(), zone_manager::rotate_zones(), conditional_t< T >::set_is_outside(), target_ui::set_last_target(), shoot(), iexamine::shrub_wildveggies(), smash(), spawn_monsters_submap_group(), debug_menu::spawn_nested_mapgen(), spread_gas(), ter_set(), tidy_activity(), vehicle::total_wind_epower_w(), translate_radius(), iexamine::trap(), update_suspension_cache(), use_charges_from_furn(), iexamine::use_furn_fake_item(), basecamp::validate_sort_points(), vehicle_activity(), vertical_move_destination(), iuse::weather_tool(), npc::worker_downtime(), and game::zones_manager().

◆ getlocal() [1/2]

point map::getlocal ( const point p) const
inline

Definition at line 1635 of file map.h.

1635 {
1636 return getlocal( tripoint( p, abs_sub.z ) ).xy();
1637 }

References abs_sub, getlocal(), tripoint::xy(), and tripoint::z.

◆ getlocal() [2/2]

tripoint map::getlocal ( const tripoint p) const

Inverse of getabs.

Definition at line 8079 of file map.cpp.

8080{
8081 return p - sm_to_ms_copy( abs_sub.xy() );
8082}

References abs_sub, sm_to_ms_copy(), and tripoint::xy().

Referenced by basecamp::abandon_camp(), activity_on_turn_move_loot(), zone_manager::add(), add_basecamp_storage_to_loot_zone_list(), grid_furn_transform_queue::apply(), talk_function::basecamp_mission(), activity_handlers::build_do_turn(), can_do_activity_there(), Character::check_outbounds_activity(), activity_handlers::chop_logs_finish(), activity_handlers::chop_planks_finish(), activity_handlers::chop_tree_do_turn(), activity_handlers::chop_tree_finish(), activity_handlers::churn_finish(), cleanup_tiles(), complete_construction(), veh_interact::complete_vehicle(), vehicle::autodrive_controller::compute_obstacles(), basecamp_action_components::consume_components(), deregister_vehicle_zone(), basecamp::distribute_food(), construct::done_digormine_stair(), construct::done_mine_upstair(), editmap::edit_mapgen(), npc::execute_action(), fetch_activity(), find_auto_consume(), game::find_or_make_stairs(), find_refuel_spot_zone(), activity_handlers::forage_finish(), basecamp::form_crafting_inventory(), inventory::form_from_zone(), generic_multi_activity_check_requirement(), generic_multi_activity_handler(), generic_multi_activity_locations(), zone_manager::get_point_set_loot(), getlocal(), npc::go_to_omt_destination(), npc::good_escape_direction(), Character::has_destination_activity(), activity_handlers::jackhammer_do_turn(), activity_handlers::jackhammer_finish(), activity_handlers::milk_finish(), npc::move(), npc::move_to(), map_cursor::operator tripoint(), perform_zone_activity_turn(), activity_handlers::pickaxe_do_turn(), activity_handlers::pickaxe_finish(), teleporter_list::place_avatar_overmap(), basecamp::place_results(), game::place_vehicle_nearby(), activity_handlers::plant_seed_finish(), vehicle_part::properties_to_item(), activity_handlers::pulp_do_turn(), plot_options::query_seed(), npc::reach_omt_destination(), target_ui::recalc_aim_turning_penalty(), npc::regen_ai_cache(), requirements_map(), zone_manager::revert_vzones(), rotate(), zone_manager::rotate_zones(), activity_handlers::shear_finish(), debug_menu::spawn_nested_mapgen(), tidy_activity(), activity_handlers::travel_do_turn(), target_ui::try_reacquire_target(), update_suspension_cache(), basecamp::validate_sort_points(), activity_handlers::vehicle_finish(), vertical_move_destination(), npc::worker_downtime(), and game::zones_manager().

◆ getmapsize()

int map::getmapsize ( ) const
inline

Definition at line 1652 of file map.h.

1652 {
1653 return my_MAPSIZE;
1654 }

References my_MAPSIZE.

Referenced by distribution_grid_tracker::load(), editmap::mapgen_preview(), and points_in_range().

◆ getsubmap()

submap * map::getsubmap ( size_t  grididx) const
private

Get the submap pointer with given index in grid, the index must be valid!

Definition at line 8094 of file map.cpp.

8095{
8096 if( grididx >= grid.size() ) {
8097 debugmsg( "Tried to access invalid grid index %d. Grid size: %d", grididx, grid.size() );
8098 return nullptr;
8099 }
8100 return grid[grididx];
8101}

References debugmsg, and grid.

Referenced by generate(), get_submap_at_grid(), and saven().

◆ graffiti_at()

const std::string & map::graffiti_at ( const tripoint p) const

Definition at line 7680 of file map.cpp.

7681{
7682 if( !inbounds( p ) ) {
7683 static const std::string empty_string;
7684 return empty_string;
7685 }
7686 point l;
7687 submap *const current_submap = get_submap_at( p, l );
7688 return current_submap->get_graffiti( l );
7689}
const std::string & get_graffiti(const point &p) const
Definition: submap.cpp:88

References submap::get_graffiti(), get_submap_at(), and inbounds().

Referenced by advanced_inv_area::init(), game::place_player(), game::print_graffiti_info(), and editmap::update_view_with_help().

◆ grow_plant()

void map::grow_plant ( const tripoint p)
protected

Try to grow a harvestable plant to the next stage(s).

Definition at line 7009 of file map.cpp.

7010{
7011 const auto &furn = this->furn( p ).obj();
7012 if( !furn.has_flag( "PLANT" ) ) {
7013 return;
7014 }
7015 // Can't use item_stack::only_item() since there might be fertilizer
7016 map_stack items = i_at( p );
7017 map_stack::iterator seed = std::find_if( items.begin(), items.end(), []( const item & it ) {
7018 return it.is_seed();
7019 } );
7020
7021 if( seed == items.end() ) {
7022 // No seed there anymore, we don't know what kind of plant it was.
7023 // TODO: Fix point types
7024 const oter_id ot = overmap_buffer.ter( project_to<coords::omt>( tripoint_abs_ms( getabs( p ) ) ) );
7025 dbg( DL::Error ) << "a planted item at " << p
7026 << " (within overmap terrain " << ot.id().str() << ") has no seed data";
7027 i_clear( p );
7028 furn_set( p, f_null );
7029 return;
7030 }
7031 const time_duration plantEpoch = seed->get_plant_epoch();
7032 if( seed->age() >= plantEpoch * furn.plant->growth_multiplier &&
7033 !furn.has_flag( "GROWTH_HARVEST" ) ) {
7034 if( seed->age() < plantEpoch * 2 ) {
7035 if( has_flag_furn( "GROWTH_SEEDLING", p ) ) {
7036 return;
7037 }
7038
7039 // Remove fertilizer if any
7040 map_stack::iterator fertilizer = std::find_if( items.begin(), items.end(), []( const item & it ) {
7041 return it.has_flag( "FERTILIZER" );
7042 } );
7043 if( fertilizer != items.end() ) {
7044 items.erase( fertilizer );
7045 }
7046
7047 rotten_item_spawn( *seed, p );
7048 furn_set( p, furn_str_id( furn.plant->transform ) );
7049 } else if( seed->age() < plantEpoch * 3 * furn.plant->growth_multiplier ) {
7050 if( has_flag_furn( "GROWTH_MATURE", p ) ) {
7051 return;
7052 }
7053
7054 // Remove fertilizer if any
7055 map_stack::iterator fertilizer = std::find_if( items.begin(), items.end(), []( const item & it ) {
7056 return it.has_flag( "FERTILIZER" );
7057 } );
7058 if( fertilizer != items.end() ) {
7059 items.erase( fertilizer );
7060 }
7061
7062 rotten_item_spawn( *seed, p );
7063 //You've skipped the seedling stage so roll monsters twice
7064 if( !has_flag_furn( "GROWTH_SEEDLING", p ) ) {
7065 rotten_item_spawn( *seed, p );
7066 }
7067 furn_set( p, furn_str_id( furn.plant->transform ) );
7068 } else {
7069 //You've skipped two stages so roll monsters two times
7070 if( has_flag_furn( "GROWTH_SEEDLING", p ) ) {
7071 rotten_item_spawn( *seed, p );
7072 rotten_item_spawn( *seed, p );
7073 //One stage change
7074 } else if( has_flag_furn( "GROWTH_MATURE", p ) ) {
7075 rotten_item_spawn( *seed, p );
7076 //Goes from seed to harvest in one check
7077 } else {
7078 rotten_item_spawn( *seed, p );
7079 rotten_item_spawn( *seed, p );
7080 rotten_item_spawn( *seed, p );
7081 }
7082 furn_set( p, furn_str_id( furn.plant->transform ) );
7083 }
7084 }
7085}
iterator erase(const_iterator it) override
Definition: map.cpp:148
void rotten_item_spawn(const item &item, const tripoint &p)
Checks to see if the item that is rotting away generates a creature when it does.
Definition: map.cpp:6961
string_id< furn_t > furn_str_id
Definition: type_id.h:58

References item_stack::begin(), dbg, item_stack::end(), map_stack::erase(), Error, f_null, furn(), furn_set(), getabs(), has_flag_furn(), i_at(), i_clear(), int_id< T >::id(), int_id< T >::obj(), overmap_buffer, rotten_item_spawn(), iuse::seed(), string_id< T >::str(), and overmapbuffer::ter().

Referenced by actualize().

◆ has_adjacent_furniture_with()

bool map::has_adjacent_furniture_with ( const tripoint p,
const std::function< bool(const furn_t &)> &  filter 
)

Returns true if there is furniture for which filter returns true in a 1 tile radius of p.

Pass return_true<furn_t> to detect all adjacent furniture.

Parameters
pthe location to check at
filterwhat to filter the furniture by.

Definition at line 2736 of file map.cpp.

2738{
2739 for( const tripoint &adj : points_in_radius( p, 1 ) ) {
2740 if( has_furn( adj ) && filter( furn( adj ).obj() ) ) {
2741 return true;
2742 }
2743 }
2744
2745 return false;
2746}

References furn(), has_furn(), and points_in_radius().

◆ has_flag() [1/4]

bool map::has_flag ( const std::string &  flag,
const point p 
) const
inline

Definition at line 938 of file map.h.

938 {
939 return has_flag( flag, tripoint( p, abs_sub.z ) );
940 }

References abs_sub, has_flag(), and tripoint::z.

◆ has_flag() [2/4]

bool map::has_flag ( const std::string &  flag,
const tripoint p 
) const

Definition at line 2288 of file map.cpp.

2289{
2290 return has_flag_ter_or_furn( flag, p ); // Does bound checking
2291}

References has_flag_ter_or_furn().

Referenced by accessible_items(), Character::activate_bionic(), add_item(), add_item_or_charges(), npc::assess_danger(), bash(), bash_ter_furn(), bash_ter_success(), start_location::burn(), activity_handlers::burrow_finish(), game::butcher(), can_do_activity_there(), can_examine_at(), can_move_vertical_at(), can_put_items_ter_furn(), monster::can_reach_to(), iexamine::chainfence(), construct::check_empty(), vehicle::check_falling_or_floating(), construct::check_support(), chop_tree_activity(), climb_difficulty(), close_door(), doors::close_door(), collapse_at(), collapse_check(), consider_butchery(), iexamine::curtains(), displace_water(), dont_draw_lower_floor(), iexamine::door_peephole(), draw_lab(), drop_everything(), drop_or_embed_projectile(), iexamine::elevator(), explosion_handler::emp_blast(), game::examine(), computer_session::failure_shutdown(), features(), find_closest_stair(), game::find_or_make_stairs(), flammable_items_at(), game::fling_creature(), game::forced_door_closing(), generic_multi_activity_do(), game::get_dangerous_tile(), get_fire_fuel_string(), game::get_fishable_locations(), overmap_ui::get_overmap_path_to(), game::grabbed_furn_move(), has_flag(), has_nearby_chair(), has_nearby_table(), haul(), hit_with_fire(), is_divable(), game::is_empty(), is_flammable(), is_water_shallow_current(), game::knockback(), mine_activity(), mop_spills(), monster::move(), avatar_action::move(), npc::move_to(), move_vehicle(), game::moving_vehicle_dismount(), MapExtras::mx_minefield(), item::on_drop(), open(), open_door(), vehicle::part_collision(), activity_handlers::pickaxe_finish(), game::place_player(), game::print_fields_info(), game::print_items_info(), process_fields_in_submap(), propagate_field(), propagate_suspension_check(), avatar_action::ramp_move(), rate_location(), route(), Character::run_cost(), conditional_t< T >::set_is_outside(), vehicle::shift_zlevel(), shoot(), spawn_an_item(), spawn_items(), fungal_effects::spread_fungus(), fungal_effects::spread_fungus_one_tile(), monster::stumble(), avatar_action::swim(), game::update_stair_monsters(), editmap::update_view_with_help(), place_trap_actor::use(), deploy_tent_actor::use(), use_charges_from_furn(), game::use_computer(), game::vertical_move(), vertical_move_destination(), game::walk_move(), water_from(), and npc::worker_downtime().

◆ has_flag() [3/4]

bool map::has_flag ( ter_bitflags  flag,
const point p 
) const
inline

Definition at line 969 of file map.h.

969 {
970 return has_flag( flag, tripoint( p, abs_sub.z ) );
971 }

References abs_sub, has_flag(), and tripoint::z.

◆ has_flag() [4/4]

bool map::has_flag ( ter_bitflags  flag,
const tripoint p 
) const

Definition at line 2331 of file map.cpp.

2332{
2333 return has_flag_ter_or_furn( flag, p ); // Does bound checking
2334}

References has_flag_ter_or_furn().

◆ has_flag_furn() [1/4]

bool map::has_flag_furn ( const std::string &  flag,
const point p 
) const
inline

Definition at line 958 of file map.h.

958 {
959 return has_flag_furn( flag, tripoint( p, abs_sub.z ) );
960 }

References abs_sub, has_flag_furn(), and tripoint::z.

◆ has_flag_furn() [2/4]

◆ has_flag_furn() [3/4]

bool map::has_flag_furn ( ter_bitflags  flag,
const point p 
) const
inline

Definition at line 979 of file map.h.

979 {
980 return has_flag_furn( flag, tripoint( p, abs_sub.z ) );
981 }

References abs_sub, has_flag_furn(), and tripoint::z.

◆ has_flag_furn() [4/4]

bool map::has_flag_furn ( ter_bitflags  flag,
const tripoint p 
) const

Definition at line 2341 of file map.cpp.

2342{
2343 return furn( p ).obj().has_flag( flag );
2344}

References furn(), map_data_common_t::has_flag(), and int_id< T >::obj().

◆ has_flag_ter() [1/4]

bool map::has_flag_ter ( const std::string &  flag,
const point p 
) const
inline

Definition at line 953 of file map.h.

953 {
954 return has_flag_ter( flag, tripoint( p, abs_sub.z ) );
955 }

References abs_sub, has_flag_ter(), and tripoint::z.

◆ has_flag_ter() [2/4]

◆ has_flag_ter() [3/4]

bool map::has_flag_ter ( ter_bitflags  flag,
const point p 
) const
inline

Definition at line 974 of file map.h.

974 {
975 return has_flag_ter( flag, tripoint( p, abs_sub.z ) );
976 }

References abs_sub, has_flag_ter(), and tripoint::z.

◆ has_flag_ter() [4/4]

bool map::has_flag_ter ( ter_bitflags  flag,
const tripoint p 
) const

Definition at line 2336 of file map.cpp.

2337{
2338 return ter( p ).obj().has_flag( flag );
2339}

References map_data_common_t::has_flag(), int_id< T >::obj(), and ter().

◆ has_flag_ter_or_furn() [1/4]

bool map::has_flag_ter_or_furn ( const std::string &  flag,
const point p 
) const
inline

Definition at line 963 of file map.h.

963 {
964 return has_flag_ter_or_furn( flag, tripoint( p, abs_sub.z ) );
965 }

References abs_sub, has_flag_ter_or_furn(), and tripoint::z.

◆ has_flag_ter_or_furn() [2/4]

◆ has_flag_ter_or_furn() [3/4]

bool map::has_flag_ter_or_furn ( ter_bitflags  flag,
const point p 
) const
inline

Definition at line 984 of file map.h.

984 {
985 return has_flag_ter_or_furn( flag, tripoint( p, abs_sub.z ) );
986 }

References abs_sub, has_flag_ter_or_furn(), and tripoint::z.

◆ has_flag_ter_or_furn() [4/4]

bool map::has_flag_ter_or_furn ( ter_bitflags  flag,
const tripoint p 
) const

Definition at line 2346 of file map.cpp.

2347{
2348 if( !inbounds( p ) ) {
2349 return false;
2350 }
2351
2352 point l;
2353 submap *const current_submap = get_submap_at( p, l );
2354
2355 return current_submap && //FIXME: can be null during mapgen
2356 ( current_submap->get_ter( l ).obj().has_flag( flag ) ||
2357 current_submap->get_furn( l ).obj().has_flag( flag ) );
2358}

References submap::get_furn(), get_submap_at(), submap::get_ter(), map_data_common_t::has_flag(), inbounds(), and int_id< T >::obj().

◆ has_floor()

bool map::has_floor ( const tripoint p) const

◆ has_floor_or_support()

bool map::has_floor_or_support ( const tripoint p) const

Definition at line 2034 of file map.cpp.

2035{
2036 const tripoint below( p.xy(), p.z - 1 );
2037 return !valid_move( p, below, false, true );
2038}

References valid_move(), tripoint::xy(), and tripoint::z.

Referenced by monster::move(), game::print_terrain_info(), avatar_action::ramp_move(), reachable_flood_steps(), smash(), and game::vertical_move().

◆ has_furn() [1/2]

bool map::has_furn ( const point p) const
inline

Definition at line 823 of file map.h.

823 {
824 return has_furn( tripoint( p, abs_sub.z ) );
825 }

References abs_sub, has_furn(), and tripoint::z.

◆ has_furn() [2/2]

◆ has_graffiti_at()

bool map::has_graffiti_at ( const tripoint p) const

Definition at line 7691 of file map.cpp.

7692{
7693 if( !inbounds( p ) ) {
7694 return false;
7695 }
7696 point l;
7697 submap *const current_submap = get_submap_at( p, l );
7698 return current_submap->has_graffiti( l );
7699}
bool has_graffiti(const point &p) const
Definition: submap.cpp:83

References get_submap_at(), submap::has_graffiti(), and inbounds().

Referenced by editmap::draw_main_ui_overlay(), advanced_inv_area::init(), game::place_player(), game::print_graffiti_info(), and editmap::update_view_with_help().

◆ has_items()

bool map::has_items ( const tripoint p) const

Checks for existence of items.

Faster than i_at(p).empty

Definition at line 4750 of file map.cpp.

4751{
4752 if( !inbounds( p ) ) {
4753 return false;
4754 }
4755
4756 point l;
4757 submap *const current_submap = get_submap_at( p, l );
4758
4759 return !current_submap->get_items( l ).empty();
4760}

References submap::get_items(), get_submap_at(), and inbounds().

Referenced by Character::activate_bionic(), bash_items(), can_do_activity_there(), can_examine_at(), can_pickup_at(), drop_furniture(), drop_items(), flammable_items_at(), inventory::form_from_map(), generate_lightmap(), has_clear_path_to_pickup_items(), haul(), iuse::note_bionics(), npc::pick_up_item(), game::place_player(), sees_some_items(), and smash_items().

◆ has_nearby_chair()

bool map::has_nearby_chair ( const tripoint p,
int  radius = 1 
)

Check whether a chair or vehicle seat is nearby.

Definition at line 2775 of file map.cpp.

2776{
2777 for( const tripoint &pt : points_in_radius( p, radius ) ) {
2778 const optional_vpart_position vp = veh_at( pt );
2779 if( has_flag( "CAN_SIT", pt ) ) {
2780 return true;
2781 }
2782 if( vp && vp->vehicle().has_part( "SEAT" ) ) {
2783 return true;
2784 }
2785 }
2786 return false;
2787}

References has_flag(), points_in_radius(), and veh_at().

◆ has_nearby_fire()

bool map::has_nearby_fire ( const tripoint p,
int  radius = 1 
)

Definition at line 2748 of file map.cpp.

2749{
2750 for( const tripoint &pt : points_in_radius( p, radius ) ) {
2751 if( get_field( pt, fd_fire ) != nullptr ) {
2752 return true;
2753 }
2754 if( has_flag_ter_or_furn( "USABLE_FIRE", pt ) ) {
2755 return true;
2756 }
2757 }
2758 return false;
2759}

References fd_fire, get_field(), has_flag_ter_or_furn(), and points_in_radius().

Referenced by iexamine::fireplace(), and inventory::form_from_map().

◆ has_nearby_table()

bool map::has_nearby_table ( const tripoint p,
int  radius = 1 
)

Check whether a table/workbench/vehicle kitchen or other flat surface is nearby that could be used for crafting or eating.

Definition at line 2761 of file map.cpp.

2762{
2763 for( const tripoint &pt : points_in_radius( p, radius ) ) {
2764 const optional_vpart_position vp = veh_at( p );
2765 if( has_flag( "FLAT_SURF", pt ) ) {
2766 return true;
2767 }
2768 if( vp && ( vp->vehicle().has_part( "KITCHEN" ) || vp->vehicle().has_part( "FLAT_SURF" ) ) ) {
2769 return true;
2770 }
2771 }
2772 return false;
2773}

References has_flag(), points_in_radius(), and veh_at().

Referenced by can_do_activity_there(), and consider_butchery().

◆ has_zlevels()

◆ hit_with_acid()

bool map::hit_with_acid ( const tripoint p)

Definition at line 3809 of file map.cpp.

3810{
3811 if( passable( p ) ) {
3812 return false; // Didn't hit the tile!
3813 }
3814 const ter_id t = ter( p );
3815 if( t == t_wall_glass || t == t_wall_glass_alarm ||
3816 t == t_vat ) {
3817 ter_set( p, t_floor );
3818 } else if( t == t_door_c || t == t_door_locked || t == t_door_locked_peep ||
3819 t == t_door_locked_alarm ) {
3820 if( one_in( 3 ) ) {
3821 ter_set( p, t_door_b );
3822 }
3823 } else if( t == t_door_bar_c || t == t_door_bar_o || t == t_door_bar_locked || t == t_bars ||
3824 t == t_reb_cage ) {
3825 ter_set( p, t_floor );
3826 add_msg( m_warning, _( "The metal bars melt!" ) );
3827 } else if( t == t_door_b ) {
3828 if( one_in( 4 ) ) {
3829 ter_set( p, t_door_frame );
3830 } else {
3831 return false;
3832 }
3833 } else if( t == t_window || t == t_window_alarm || t == t_window_no_curtains ) {
3834 ter_set( p, t_window_empty );
3835 } else if( t == t_wax ) {
3836 ter_set( p, t_floor_wax );
3837 } else if( t == t_gas_pump || t == t_gas_pump_smashed ) {
3838 return false;
3839 } else if( t == t_card_science || t == t_card_military || t == t_card_industrial ) {
3841 }
3842 return true;
3843}
@ m_warning
Definition: enums.h:257
ter_id t_card_industrial
Definition: mapdata.cpp:722
ter_id t_floor_wax
Definition: mapdata.cpp:685
ter_id t_reb_cage
Definition: mapdata.cpp:654
ter_id t_card_military
Definition: mapdata.cpp:722
ter_id t_door_bar_locked
Definition: mapdata.cpp:663
ter_id t_window_alarm
Definition: mapdata.cpp:668
ter_id t_door_bar_o
Definition: mapdata.cpp:663
ter_id t_gas_pump
Definition: mapdata.cpp:698
ter_id t_wall_glass_alarm
Definition: mapdata.cpp:649
ter_id t_card_reader_broken
Definition: mapdata.cpp:722
ter_id t_gas_pump_smashed
Definition: mapdata.cpp:698
ter_id t_door_locked_peep
Definition: mapdata.cpp:657
ter_id t_door_bar_c
Definition: mapdata.cpp:663
ter_id t_door_frame
Definition: mapdata.cpp:658
ter_id t_vat
Definition: mapdata.cpp:710
ter_id t_window_no_curtains
Definition: mapdata.cpp:672
ter_id t_wax
Definition: mapdata.cpp:685
ter_id t_window_empty
Definition: mapdata.cpp:668
ter_id t_door_b
Definition: mapdata.cpp:656

References _, add_msg(), m_warning, one_in(), passable(), t_bars, t_card_industrial, t_card_military, t_card_reader_broken, t_card_science, t_door_b, t_door_bar_c, t_door_bar_locked, t_door_bar_o, t_door_c, t_door_frame, t_door_locked, t_door_locked_alarm, t_door_locked_peep, t_floor, t_floor_wax, t_gas_pump, t_gas_pump_smashed, t_reb_cage, t_vat, t_wall_glass, t_wall_glass_alarm, t_wax, t_window, t_window_alarm, t_window_empty, t_window_no_curtains, ter(), and ter_set().

◆ hit_with_fire()

bool map::hit_with_fire ( const tripoint p)

Definition at line 3846 of file map.cpp.

3847{
3848 if( passable( p ) ) {
3849 return false; // Didn't hit the tile!
3850 }
3851
3852 // non passable but flammable terrain, set it on fire
3853 if( has_flag( "FLAMMABLE", p ) || has_flag( "FLAMMABLE_ASH", p ) ) {
3854 add_field( p, fd_fire, 3 );
3855 }
3856 return true;
3857}

References add_field(), fd_fire, has_flag(), and passable().

◆ hoist_submap_camp()

basecamp map::hoist_submap_camp ( const tripoint p)

Definition at line 5551 of file map.cpp.

5552{
5553 basecamp *pcamp = get_submap_at( p )->camp.get();
5554 return pcamp ? *pcamp : basecamp();
5555}
std::unique_ptr< basecamp > camp
Definition: submap.h:249

References submap::camp, and get_submap_at().

Referenced by game::validate_camps().

◆ i_at() [1/2]

map_stack map::i_at ( const point p)
inline

Definition at line 1210 of file map.h.

1210 {
1211 return i_at( tripoint( p, abs_sub.z ) );
1212 }

References abs_sub, i_at(), and tripoint::z.

◆ i_at() [2/2]

map_stack map::i_at ( const tripoint p)

Definition at line 4069 of file map.cpp.

4070{
4071 if( !inbounds( p ) ) {
4072 nulitems.clear();
4073 return map_stack{ &nulitems, p, this };
4074 }
4075
4076 point l;
4077 submap *const current_submap = get_submap_at( p, l );
4078
4079 return map_stack{ &current_submap->get_items( l ), p, this };
4080}
static cata::colony< item > nulitems
Definition: map.cpp:138

References submap::get_items(), get_submap_at(), inbounds(), and nulitems.

Referenced by computer_session::action_blood_anal(), computer_session::action_conveyor(), computer_session::action_data_anal(), computer_session::action_irradiator(), computer_session::action_list_bionics(), computer_session::action_sample(), Character::activate_bionic(), activity_on_turn_move_loot(), add_item_or_charges(), advanced_inventory_pane::add_items_from_area(), iexamine::aggie_plant(), apply_camp_ownership(), apply_faction_ownership(), iexamine::arcfurnace_empty(), iexamine::arcfurnace_full(), are_requirements_nearby(), iexamine::autoclave_full(), Character::base_comfort_value(), bash_furn_success(), bash_items(), board_up(), MapExtras::burned_ground_parser(), game::butcher(), butcher_corpse_activity(), can_butcher_at(), can_do_activity_there(), iexamine::can_fertilize(), advanced_inventory::change_square(), construct::check_empty(), chop_plank_activity(), doors::close_door(), complete_construction(), iuse::directional_antenna(), iexamine::dirtmound(), displace_items_except_one_liquid(), basecamp::distribute_food(), construct::done_grave(), drop_furniture(), drop_items(), editmap::edit_itm(), iexamine::elevator(), explosion_handler::emp_blast(), game::examine(), computer_session::failure_destroy_blood(), computer_session::failure_destroy_data(), farm_action(), iexamine::fertilize_plant(), fetch_activity(), talk_function::field_harvest(), fill_funnels(), activity_handlers::fill_liquid_do_turn(), find_auto_consume(), npc::find_corpse_to_pulp(), npc::find_item(), game::find_nearby_items(), flammable_items_at(), Character::floor_item_warmth(), game::forced_door_closing(), basecamp::form_crafting_inventory(), inventory::form_from_map(), free_volume(), fromPumpFuel(), furnname(), iexamine::fvat_empty(), iexamine::fvat_full(), iexamine::gaspump(), generate_lightmap(), generic_multi_activity_locations(), advanced_inv_area::get_container(), player::get_eligible_containers_for_crafting(), advanced_inv_area::get_item_count(), iexamine::getNearFilledGasTank(), game::grabbed_furn_move(), grow_plant(), liquid_handler::handle_liquid_from_ground(), iexamine::harvest_plant(), i_at(), i_rem(), Character::is_snuggling(), activity_handlers::jackhammer_finish(), iexamine::keg(), iexamine::kiln_empty(), iexamine::kiln_full(), advanced_inventory_pane::load_settings(), activity_handlers::longsalvage_finish(), talk_function::loot_building(), max_volume(), mill_activate(), iexamine::mill_finalize(), mop_spills(), advanced_inventory::move_all_items(), MapExtras::mx_supplydrop(), iuse::note_bionics(), om_harvest_itm(), iexamine::pedestal_temple(), iexamine::pedestal_wyrm(), tutorial_game::per_turn(), npc::pick_up_item_map(), activity_handlers::pickaxe_finish(), game::place_player(), iexamine::pour_into_keg(), firestarter_actor::prep_firestarter_use(), game::print_items_info(), process_fields_in_submap(), process_items_in_submap(), produce_sap(), activity_handlers::pulp_do_turn(), iexamine::quern_examine(), plot_options::query_seed(), iexamine::recycle_compactor(), iexamine::reload_furniture(), requirements_map(), rod_fish(), npc::see_item_say_smth(), serialize_liquid_source(), iexamine::shrub_wildveggies(), smash(), smash_items(), smoker_activate(), smoker_finalize(), iexamine::smoker_options(), fungal_effects::spread_fungus_one_tile(), game::start_hauling(), basecamp::start_relay_hide_site(), stored_volume(), tidy_activity(), tinder_at(), iexamine::toilet(), iexamine::toPumpFuel(), iexamine::tree_maple_tapped(), try_fuel_fire(), editmap::update_view_with_help(), use_amount_square(), use_charges(), use_charges_from_furn(), iexamine::use_furn_fake_item(), and iexamine::vending().

◆ i_clear() [1/2]

void map::i_clear ( const point p)
inline

Definition at line 1215 of file map.h.

1215 {
1216 i_clear( tripoint( p, abs_sub.z ) );
1217 }

References abs_sub, i_clear(), and tripoint::z.

◆ i_clear() [2/2]

void map::i_clear ( const tripoint p)

Definition at line 4107 of file map.cpp.

4108{
4109 point l;
4110 submap *const current_submap = get_submap_at( p, l );
4111
4112 for( item &it : current_submap->get_items( l ) ) {
4113 // remove from the active items cache (if it isn't there does nothing)
4114 current_submap->active_items.remove( &it );
4115 }
4116 if( current_submap->active_items.empty() ) {
4117 submaps_with_active_items.erase( tripoint( abs_sub.x + p.x / SEEX, abs_sub.y + p.y / SEEY, p.z ) );
4118 }
4119
4120 current_submap->set_lum( l, 0 );
4121 current_submap->get_items( l ).clear();
4122}
void remove(const item *it)
Removes the item if it is in the cache.
void set_lum(const point &p, uint8_t luminance)
Definition: submap.h:125

References abs_sub, submap::active_items, active_item_cache::empty(), submap::get_items(), get_submap_at(), active_item_cache::remove(), SEEX, SEEY, submap::set_lum(), submaps_with_active_items, tripoint::x, tripoint::y, and tripoint::z.

Referenced by computer_session::action_conveyor(), iexamine::aggie_plant(), jmapgen_terrain::apply(), iexamine::arcfurnace_empty(), board_up(), doors::close_door(), MapExtras::dead_vegetation_parser(), basecamp::distribute_food(), draw_lab(), drop_furniture(), drop_items(), computer_session::failure_destroy_blood(), computer_session::failure_destroy_data(), farm_action(), iexamine::fertilize_plant(), talk_function::field_harvest(), iexamine::fvat_empty(), iexamine::fvat_full(), game::grabbed_furn_move(), grow_plant(), iexamine::harvest_plant(), i_clear(), iexamine::keg(), iexamine::kiln_empty(), mapgen_lake_shore(), om_harvest_itm(), iexamine::pedestal_temple(), iexamine::pedestal_wyrm(), rad_scorch(), and iexamine::tree_maple_tapped().

◆ i_rem() [1/4]

map_stack::iterator map::i_rem ( const point location,
map_stack::const_iterator  it 
)
inline

Definition at line 1221 of file map.h.

1221 {
1222 return i_rem( tripoint( location, abs_sub.z ), it );
1223 }
map_stack::iterator i_rem(const tripoint &p, map_stack::const_iterator it)
Definition: map.cpp:4082

References abs_sub, i_rem(), and tripoint::z.

◆ i_rem() [2/4]

void map::i_rem ( const point p,
item it 
)
inline

Definition at line 1225 of file map.h.

1225 {
1226 i_rem( tripoint( p, abs_sub.z ), it );
1227 }

References abs_sub, i_rem(), and tripoint::z.

◆ i_rem() [3/4]

void map::i_rem ( const tripoint p,
item it 
)

Definition at line 4098 of file map.cpp.

4099{
4100 map_stack map_items = i_at( p );
4102 if( iter != map_items.end() ) {
4103 i_rem( p, iter );
4104 }
4105}
iterator get_iterator_from_pointer(item *it)
Definition: item_stack.cpp:68

References item_stack::end(), item_stack::get_iterator_from_pointer(), i_at(), and i_rem().

◆ i_rem() [4/4]

map_stack::iterator map::i_rem ( const tripoint p,
map_stack::const_iterator  it 
)

Definition at line 4082 of file map.cpp.

4083{
4084 point l;
4085 submap *const current_submap = get_submap_at( p, l );
4086
4087 // remove from the active items cache (if it isn't there does nothing)
4088 current_submap->active_items.remove( &*it );
4089 if( current_submap->active_items.empty() ) {
4090 submaps_with_active_items.erase( tripoint( abs_sub.x + p.x / SEEX, abs_sub.y + p.y / SEEY, p.z ) );
4091 }
4092
4093 current_submap->update_lum_rem( l, *it );
4094
4095 return current_submap->get_items( l ).erase( it );
4096}
void update_lum_rem(const point &p, const item &i)
Definition: submap.h:137

References abs_sub, submap::active_items, active_item_cache::empty(), submap::get_items(), get_submap_at(), active_item_cache::remove(), SEEX, SEEY, submaps_with_active_items, submap::update_lum_rem(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by computer_session::action_irradiator(), chop_plank_activity(), iexamine::elevator(), iexamine::fvat_full(), get_map(), i_rem(), mill_activate(), move_item(), om_set_hide_site(), rcdrive(), remove_rotten_items(), game::save_cyborg(), smash_items(), and smoker_activate().

◆ impassable() [1/2]

bool map::impassable ( const point p) const
inline

Definition at line 611 of file map.h.

611 {
612 return !passable( p );
613 }

References passable().

◆ impassable() [2/2]

◆ impassable_ter_furn()

bool map::impassable_ter_furn ( const tripoint p) const

Definition at line 1823 of file map.cpp.

1824{
1825 return !passable_ter_furn( p );
1826}
bool passable_ter_furn(const tripoint &p) const
Definition: map.cpp:1828

References passable_ter_furn().

Referenced by vehicle::check_heli_ascend(), vehicle::check_heli_descend(), climb_difficulty(), displace_water(), and vehicle::part_collision().

◆ inbounds() [1/2]

bool map::inbounds ( const point p) const
inline

Definition at line 1639 of file map.h.

1639 {
1640 return inbounds( tripoint( p, 0 ) );
1641 }

References inbounds().

◆ inbounds() [2/2]

bool map::inbounds ( const tripoint p) const
virtual

Reimplemented in tinymap.

Definition at line 7614 of file map.cpp.

7615{
7616 static constexpr tripoint map_boundary_min( 0, 0, -OVERMAP_DEPTH );
7617 static constexpr tripoint map_boundary_max( MAPSIZE_Y, MAPSIZE_X, OVERMAP_HEIGHT + 1 );
7618
7619 static constexpr half_open_cuboid<tripoint> map_boundaries(
7620 map_boundary_min, map_boundary_max );
7621
7622 return map_boundaries.contains( p );
7623}

References half_open_cuboid< Tripoint, >::contains(), MAPSIZE_X, MAPSIZE_Y, OVERMAP_DEPTH, and OVERMAP_HEIGHT.

Referenced by vehicle::act_on_map(), activity_on_turn_move_loot(), add_field(), add_item(), MapgenRemovePartHandler::add_item_or_charges(), add_item_or_charges(), add_vehicle(), add_vehicle_to_cache(), adjust_radiation(), ambient_light_at(), apply_light_source(), bash(), bash_rating(), build_sunlight_cache(), Character::check_outbounds_activity(), clear_path(), clear_vehicle_cache(), clear_vehicle_point_from_cache(), computer_at(), delete_graffiti(), delete_signage(), displace_vehicle(), explosion_handler::do_blast(), do_vehicle_caching(), draw(), game::draw_look_around_cursor(), drawsq(), ranged::execute_shaped_attack(), field_at(), furn(), furn_set(), generate_lightmap(), generic_multi_activity_handler(), get_field(), get_known_connections(), get_radiation(), get_signage(), get_submap_at(), get_temperature(), graffiti_at(), has_flag_ter_or_furn(), has_floor(), has_graffiti_at(), has_items(), i_at(), inbounds(), is_bashable(), is_outside(), light_at(), game::load_npcs(), maptile_at(), map_stack::max_volume(), move_cost(), move_cost_ter_furn(), activity_handlers::operation_do_turn(), partial_con_at(), partial_con_remove(), partial_con_set(), pl_line_of_sight(), pl_sees(), game::print_all_tile_info(), remove_field(), remove_trap(), route(), npc::saw_player_recently(), sees(), set_graffiti(), set_radiation(), set_seen_cache_dirty(), set_signage(), set_temperature(), set_transparency_cache_dirty(), game::shift_monsters(), shift_traps(), shoot(), spawn_items(), ter(), ter_set(), tr_at(), trap_set(), update_suspension_cache(), valid_move(), and veh_at().

◆ inbounds_z()

◆ invalidate_map_cache()

◆ invalidate_max_populated_zlev()

void map::invalidate_max_populated_zlev ( int  zlev)
private

Conditionally invalidates max_pupulated_zlev cache if the submap uniformity change occurs above current max_pupulated_zlev value.

Parameters
zlevzlevel where uniformity change occured

Definition at line 8768 of file map.cpp.

8769{
8770 if( max_populated_zlev && max_populated_zlev->second < zlev ) {
8771 max_populated_zlev->second = zlev;
8772 }
8773}

References max_populated_zlev.

Referenced by add_field(), add_item(), add_vehicle(), displace_vehicle(), furn_set(), shift_vehicle_z(), and ter_set().

◆ is_bashable() [1/2]

bool map::is_bashable ( const point p) const
inline

Definition at line 991 of file map.h.

991 {
992 return is_bashable( tripoint( p, abs_sub.z ) );
993 }

References abs_sub, is_bashable(), and tripoint::z.

◆ is_bashable() [2/2]

bool map::is_bashable ( const tripoint p,
bool  allow_floor = false 
) const

Returns true if there is a bashable vehicle part or the furn/terrain is bashable at p.

Definition at line 2409 of file map.cpp.

2410{
2411 if( !inbounds( p ) ) {
2412 dbg( DL::Warn ) << "Looking for out-of-bounds is_bashable at " << p;
2413 return false;
2414 }
2415
2416 if( veh_at( p ).obstacle_at_part() ) {
2417 return true;
2418 }
2419
2420 if( has_furn( p ) && furn( p ).obj().bash.str_max != -1 ) {
2421 return true;
2422 }
2423
2424 const auto &ter_bash = ter( p ).obj().bash;
2425 return ter_bash.str_max != -1 && ( !ter_bash.bash_below || allow_floor );
2426}

References bash(), map_data_common_t::bash, dbg, furn(), has_furn(), inbounds(), int_id< T >::obj(), map_bash_info::str_max, ter(), veh_at(), and Warn.

Referenced by MapExtras::burned_ground_parser(), activity_handlers::burrow_finish(), features(), game::fling_creature(), is_bashable(), npc::move_to(), MapExtras::mx_helicopter(), and activity_handlers::pickaxe_finish().

◆ is_bashable_furn() [1/2]

bool map::is_bashable_furn ( const point p) const
inline

Definition at line 1001 of file map.h.

1001 {
1002 return is_bashable_furn( tripoint( p, abs_sub.z ) );
1003 }
bool is_bashable_furn(const tripoint &p) const
Returns true if the furniture at p is bashable.
Definition: map.cpp:2434

References abs_sub, is_bashable_furn(), and tripoint::z.

◆ is_bashable_furn() [2/2]

bool map::is_bashable_furn ( const tripoint p) const

Returns true if the furniture at p is bashable.

Definition at line 2434 of file map.cpp.

2435{
2436 return has_furn( p ) && furn( p ).obj().bash.str_max != -1;
2437}

References map_data_common_t::bash, furn(), has_furn(), int_id< T >::obj(), and map_bash_info::str_max.

Referenced by is_bashable_furn(), is_bashable_ter_furn(), and make_rubble().

◆ is_bashable_ter() [1/2]

bool map::is_bashable_ter ( const point p) const
inline

Definition at line 996 of file map.h.

996 {
997 return is_bashable_ter( tripoint( p, abs_sub.z ) );
998 }
bool is_bashable_ter(const tripoint &p, bool allow_floor=false) const
Returns true if the terrain at p is bashable.
Definition: map.cpp:2428

References abs_sub, is_bashable_ter(), and tripoint::z.

◆ is_bashable_ter() [2/2]

bool map::is_bashable_ter ( const tripoint p,
bool  allow_floor = false 
) const

Returns true if the terrain at p is bashable.

Definition at line 2428 of file map.cpp.

2429{
2430 const auto &ter_bash = ter( p ).obj().bash;
2431 return ter_bash.str_max != -1 && ( !ter_bash.bash_below || allow_floor );
2432}

References map_data_common_t::bash, int_id< T >::obj(), map_bash_info::str_max, and ter().

Referenced by is_bashable_ter(), is_bashable_ter_furn(), and make_rubble().

◆ is_bashable_ter_furn() [1/2]

bool map::is_bashable_ter_furn ( const point p) const
inline

Definition at line 1006 of file map.h.

1006 {
1007 return is_bashable_ter_furn( tripoint( p, abs_sub.z ) );
1008 }
bool is_bashable_ter_furn(const tripoint &p, bool allow_floor=false) const
Returns true if the furniture or terrain at p is bashable.
Definition: map.cpp:2439

References abs_sub, is_bashable_ter_furn(), and tripoint::z.

◆ is_bashable_ter_furn() [2/2]

bool map::is_bashable_ter_furn ( const tripoint p,
bool  allow_floor = false 
) const

Returns true if the furniture or terrain at p is bashable.

Definition at line 2439 of file map.cpp.

2440{
2441 return is_bashable_furn( p ) || is_bashable_ter( p, allow_floor );
2442}

References is_bashable_furn(), and is_bashable_ter().

Referenced by is_bashable_ter_furn(), and vehicle::part_collision().

◆ is_cornerfloor()

bool map::is_cornerfloor ( const tripoint p) const

Definition at line 8705 of file map.cpp.

8706{
8707 if( impassable( p ) ) {
8708 return false;
8709 }
8710 std::set<tripoint> impassable_adjacent;
8711 for( const tripoint &pt : points_in_radius( p, 1 ) ) {
8712 if( impassable( pt ) ) {
8713 impassable_adjacent.insert( pt );
8714 }
8715 }
8716 if( !impassable_adjacent.empty() ) {
8717 //to check if a floor is a corner we first search if any of its diagonal adjacent points is impassable
8718 std::set< tripoint> diagonals = { p + tripoint_north_east, p + tripoint_north_west, p + tripoint_south_east, p + tripoint_south_west };
8719 for( const tripoint &impassable_diagonal : diagonals ) {
8720 if( impassable_adjacent.count( impassable_diagonal ) != 0 ) {
8721 //for every impassable diagonal found, we check if that diagonal terrain has at least two impassable neighbors that also neighbor point p
8722 int f = 0;
8723 for( const tripoint &l : points_in_radius( impassable_diagonal, 1 ) ) {
8724 if( impassable_adjacent.count( l ) != 0 ) {
8725 f++;
8726 }
8727 if( f > 2 ) {
8728 return true;
8729 }
8730 }
8731 }
8732 }
8733 }
8734 return false;
8735}
static constexpr tripoint tripoint_north_east
Definition: point.h:286
static constexpr tripoint tripoint_north_west
Definition: point.h:292
static constexpr tripoint tripoint_south_east
Definition: point.h:288
static constexpr tripoint tripoint_south_west
Definition: point.h:290

References impassable(), points_in_radius(), tripoint_north_east, tripoint_north_west, tripoint_south_east, and tripoint_south_west.

◆ is_divable() [1/2]

bool map::is_divable ( const point p) const
inline

Definition at line 1049 of file map.h.

1049 {
1050 return is_divable( tripoint( p, abs_sub.z ) );
1051 }
bool is_divable(const tripoint &p) const
Returns whether or not the terrain at the given location can be dived into (by monsters that can swim...
Definition: map.cpp:2553

References abs_sub, is_divable(), and tripoint::z.

◆ is_divable() [2/2]

bool map::is_divable ( const tripoint p) const

Returns whether or not the terrain at the given location can be dived into (by monsters that can swim or are aquatic or non-breathing).

Parameters
pThe coordinate to look at.
Returns
true if the terrain can be dived into; false if not.

Definition at line 2553 of file map.cpp.

2554{
2555 return has_flag( "SWIMMABLE", p ) && has_flag( TFLAG_DEEP_WATER, p );
2556}

References has_flag(), and TFLAG_DEEP_WATER.

Referenced by enchantment::is_active(), is_divable(), and Creature::sees().

◆ is_flammable()

bool map::is_flammable ( const tripoint p)

Returns true if there is a flammable item or field or the furn/terrain is flammable at p.

Definition at line 2637 of file map.cpp.

2638{
2639 if( flammable_items_at( p ) ) {
2640 return true;
2641 }
2642
2643 if( has_flag( "FLAMMABLE", p ) ) {
2644 return true;
2645 }
2646
2647 if( has_flag( "FLAMMABLE_ASH", p ) ) {
2648 return true;
2649 }
2650
2651 if( get_field_intensity( p, fd_web ) > 0 ) {
2652 return true;
2653 }
2654
2655 return false;
2656}
int get_field_intensity(const tripoint &p, const field_type_id &type) const
Get the intensity of a field entry (field_entry::intensity), if there is no field of that type,...
Definition: map.cpp:5357
bool flammable_items_at(const tripoint &p, int threshold=0)
Checks if there are any flammable items on the tile.
Definition: map.cpp:2620

References fd_web, flammable_items_at(), get_field_intensity(), and has_flag().

Referenced by Character::activate_bionic(), and activity_handlers::start_fire_do_turn().

◆ is_harvestable()

bool map::is_harvestable ( const tripoint pos) const

Returns true if point at pos is harvestable right now, with no extra tools.

Definition at line 1625 of file map.cpp.

1626{
1627 const auto &harvest_here = get_harvest( pos );
1628 return !harvest_here.is_null() && !harvest_here->empty();
1629}
const harvest_id & get_harvest(const tripoint &p) const
Returns the full harvest list, for spawning.
Definition: map.cpp:1559

References get_harvest(), and wrapped_vehicle::pos.

Referenced by npc::pick_up_item().

◆ is_last_ter_wall()

bool map::is_last_ter_wall ( bool  no_furn,
const point p,
const point max,
direction  dir 
) const

Check if the last terrain is wall in direction NORTH, SOUTH, WEST or EAST.

Parameters
no_furnif true, the function will stop and return false if it encounters a furniture
pstarting coordinates of check
maxending coordinates of check
dirDirection of check
Returns
true if from x to xmax or y to ymax depending on direction all terrain is floor and the last terrain is a wall

Definition at line 2568 of file map.cpp.

2570{
2571 point mov;
2572 switch( dir ) {
2573 case direction::NORTH:
2574 mov.y = -1;
2575 break;
2576 case direction::SOUTH:
2577 mov.y = 1;
2578 break;
2579 case direction::WEST:
2580 mov.x = -1;
2581 break;
2582 case direction::EAST:
2583 mov.x = 1;
2584 break;
2585 default:
2586 break;
2587 }
2588 point p2( p );
2589 bool result = true;
2590 bool loop = true;
2591 while( ( loop ) && ( ( dir == direction::NORTH && p2.y >= 0 ) ||
2592 ( dir == direction::SOUTH && p2.y < max.y ) ||
2593 ( dir == direction::WEST && p2.x >= 0 ) ||
2594 ( dir == direction::EAST && p2.x < max.x ) ) ) {
2595 if( no_furn && has_furn( p2 ) ) {
2596 loop = false;
2597 result = false;
2598 } else if( !has_flag_ter( "FLAT", p2 ) ) {
2599 loop = false;
2600 if( !has_flag_ter( "WALL", p2 ) ) {
2601 result = false;
2602 }
2603 }
2604 p2.x += mov.x;
2605 p2.y += mov.y;
2606 }
2607 return result;
2608}

References EAST, has_flag_ter(), has_furn(), NORTH, SOUTH, WEST, point::x, and point::y.

Referenced by find_potential_computer_point().

◆ is_outside() [1/2]

bool map::is_outside ( const point p) const
inline

Definition at line 1039 of file map.h.

1039 {
1040 return is_outside( tripoint( p, abs_sub.z ) );
1041 }
bool is_outside(const tripoint &p) const
Definition: map.cpp:2558

References abs_sub, is_outside(), and tripoint::z.

◆ is_outside() [2/2]

◆ is_suspension_valid()

bool map::is_suspension_valid ( const tripoint point)

Checks the four orientations in which a suspended tile could be valid, and returns if the tile is valid.

Definition at line 2957 of file map.cpp.

2958{
2959 if( ter( point + tripoint_east ) != t_open_air
2960 && ter( point + tripoint_west ) != t_open_air ) {
2961 return true;
2962 }
2965 return true;
2966 }
2968 && ter( point + tripoint_north ) != t_open_air ) {
2969 return true;
2970 }
2973 return true;
2974 }
2975 return false;
2976}
static constexpr tripoint tripoint_north
Definition: point.h:285
static constexpr tripoint tripoint_west
Definition: point.h:291
static constexpr tripoint tripoint_east
Definition: point.h:287
static constexpr tripoint tripoint_south
Definition: point.h:289

References t_open_air, ter(), tripoint_east, tripoint_north, tripoint_north_east, tripoint_north_west, tripoint_south, tripoint_south_east, tripoint_south_west, and tripoint_west.

Referenced by collapse_invalid_suspension(), and update_suspension_cache().

◆ is_transparent()

bool map::is_transparent ( const tripoint p) const

Returns whether the tile at p is transparent(you can look past it).

Definition at line 624 of file lightmap.cpp.

625{
627}

References light_transparency(), and LIGHT_TRANSPARENCY_SOLID.

Referenced by ranged::execute_shaped_attack(), ranged::expected_coverage(), get_known_connections(), and shoot().

◆ is_wall_adjacent()

bool map::is_wall_adjacent ( const tripoint center) const

Definition at line 1763 of file map.cpp.

1764{
1765 for( const tripoint &p : points_in_radius( center, 1 ) ) {
1766 if( p != center && impassable( p ) ) {
1767 return true;
1768 }
1769 }
1770 return false;
1771}

References center, impassable(), and points_in_radius().

Referenced by ma_requirements::is_valid_character().

◆ is_water_shallow_current() [1/2]

bool map::is_water_shallow_current ( const point p) const
inline

Definition at line 1053 of file map.h.

1053 {
1055 }
bool is_water_shallow_current(const tripoint &p) const
Definition: map.cpp:2548

References abs_sub, is_water_shallow_current(), and tripoint::z.

◆ is_water_shallow_current() [2/2]

bool map::is_water_shallow_current ( const tripoint p) const

Definition at line 2548 of file map.cpp.

2549{
2550 return has_flag( "CURRENT", p ) && !has_flag( TFLAG_DEEP_WATER, p );
2551}

References has_flag(), and TFLAG_DEEP_WATER.

Referenced by is_water_shallow_current(), and iexamine::quern_examine().

◆ light_at()

lit_level map::light_at ( const tripoint p) const

Definition at line 590 of file lightmap.cpp.

591{
592 if( !inbounds( p ) ) {
593 return lit_level::DARK; // Out of bounds
594 }
595
596 const auto &map_cache = get_cache_ref( p.z );
597 const auto &lm = map_cache.lm;
598 const auto &sm = map_cache.sm;
599 if( sm[p.x][p.y] >= LIGHT_SOURCE_BRIGHT ) {
600 return lit_level::BRIGHT;
601 }
602
603 const float max_light = lm[p.x][p.y].max();
604 if( max_light >= LIGHT_AMBIENT_LIT ) {
605 return lit_level::LIT;
606 }
607
608 if( max_light >= LIGHT_AMBIENT_LOW ) {
609 return lit_level::LOW;
610 }
611
612 return lit_level::DARK;
613}

References BRIGHT, DARK, get_cache_ref(), inbounds(), LIGHT_AMBIENT_LIT, LIGHT_AMBIENT_LOW, LIGHT_SOURCE_BRIGHT, LIT, LOW, coords::sm, tripoint::x, tripoint::y, and tripoint::z.

Referenced by Creature::sees().

◆ light_transparency()

float map::light_transparency ( const tripoint p) const

Definition at line 629 of file lightmap.cpp.

630{
631 return get_cache_ref( p.z ).transparency_cache[p.x][p.y];
632}

References get_cache_ref(), level_cache::transparency_cache, tripoint::x, tripoint::y, and tripoint::z.

Referenced by generate_lightmap(), and is_transparent().

◆ load() [1/2]

void map::load ( const tripoint w,
bool  update_vehicles 
)

Load submaps into grid.

This might create new submaps if the mapbuffer can not deliver the requested submap (as it does not exist on disc). This must be called before the map can be used at all!

Parameters
wglobal coordinates of the submap at grid[0]. This is in submap coordinates.
update_vehiclesIf true, add vehicles to the vehicle cache.

Definition at line 6494 of file map.cpp.

6495{
6496 for( auto &traps : traplocs ) {
6497 traps.clear();
6498 }
6499 field_furn_locs.clear();
6501 set_abs_sub( w );
6502 for( int gridx = 0; gridx < my_MAPSIZE; gridx++ ) {
6503 for( int gridy = 0; gridy < my_MAPSIZE; gridy++ ) {
6504 loadn( point( gridx, gridy ), update_vehicle );
6505 }
6506 }
6508}
void loadn(const tripoint &grid, bool update_vehicles)
Definition: map.cpp:6849

References field_furn_locs, loadn(), my_MAPSIZE, reset_vehicle_cache(), set_abs_sub(), submaps_with_active_items, and traplocs.

Referenced by start_location::add_map_extra(), add_monsters(), start_location::burn(), talk_function::buy_100_logs(), talk_function::buy_10_logs(), create_lab_consoles(), debug_menu::debug(), construct::done_digormine_stair(), construct::done_mine_upstair(), farm_action(), talk_function::field_build_1(), talk_function::field_build_2(), talk_function::field_harvest(), talk_function::field_plant(), find_valid_teleporters_omt(), basecamp::form_crafting_inventory(), mission_start::kill_horde_master(), load(), game::load_map(), talk_function::loot_building(), editmap::mapgen_veh_destroy(), editmap::mapgen_veh_query(), MapExtras::mx_minefield(), om_cutdown_trees(), om_harvest_furn(), om_harvest_itm(), om_harvest_ter(), om_set_hide_site(), teleporter_list::place_avatar_overmap(), Character::place_corpse(), mission_start::place_deposit_box(), mission_start::place_dog(), mission_start::place_npc_software(), mission_start::place_priest_diary(), basecamp::place_results(), game::place_vehicle_nearby(), mission_start::place_zombie_mom(), start_location::prepare_map(), mission_start::ranch_nurse_1(), mission_start::ranch_nurse_2(), mission_start::ranch_nurse_3(), mission_start::ranch_nurse_4(), mission_start::ranch_nurse_5(), mission_start::ranch_nurse_6(), mission_start::ranch_nurse_7(), mission_start::ranch_nurse_8(), mission_start::ranch_nurse_9(), mission_start::ranch_scavenger_1(), mission_start::ranch_scavenger_2(), mission_start::ranch_scavenger_3(), mission_start::reveal_lab_train_depot(), debug_menu::spawn_nested_mapgen(), basecamp::start_relay_hide_site(), update_mapgen_function_json::update_map(), game::vertical_move(), and game::vertical_shift().

◆ load() [2/2]

void map::load ( const tripoint_abs_sm w,
bool  update_vehicles 
)

Definition at line 6510 of file map.cpp.

6511{
6512 // TODO: fix point types
6513 load( w.raw(), update_vehicle );
6514}
constexpr Point & raw()
Definition: coordinates.h:111
void load(const tripoint &w, bool update_vehicles)
Load submaps into grid.
Definition: map.cpp:6494

References load(), and coords::coord_point< Point, Origin, Scale >::raw().

◆ loadn() [1/2]

void map::loadn ( const point grid,
bool  update_vehicles 
)
inlineprotected

Definition at line 1693 of file map.h.

1693 {
1694 if( zlevels ) {
1695 for( int gridz = -OVERMAP_DEPTH; gridz <= OVERMAP_HEIGHT; gridz++ ) {
1696 loadn( tripoint( grid, gridz ), update_vehicles );
1697 }
1698
1699 // Note: we want it in a separate loop! It is a post-load cleanup
1700 // Since we're adding roofs, we want it to go up (from lowest to highest)
1701 for( int gridz = -OVERMAP_DEPTH; gridz <= OVERMAP_HEIGHT; gridz++ ) {
1702 add_roofs( tripoint( grid, gridz ) );
1703 }
1704 } else {
1705 loadn( tripoint( grid, abs_sub.z ), update_vehicles );
1706 }
1707 }
void add_roofs(const tripoint &grid)
Hacks in missing roofs.
Definition: map.cpp:7318

References abs_sub, add_roofs(), grid, loadn(), OVERMAP_DEPTH, OVERMAP_HEIGHT, tripoint::z, and zlevels.

◆ loadn() [2/2]

void map::loadn ( const tripoint grid,
bool  update_vehicles 
)
protected

Definition at line 6849 of file map.cpp.

6850{
6851 // Cache empty overmap types
6852 static const oter_id rock( "empty_rock" );
6853 static const oter_id air( "open_air" );
6854
6855 const tripoint grid_abs_sub = abs_sub.xy() + grid;
6856 const size_t gridn = get_nonant( grid );
6857
6858 const int old_abs_z = abs_sub.z; // Ugly, but necessary at the moment
6859 abs_sub.z = grid.z;
6860
6861 submap *tmpsub = MAPBUFFER.lookup_submap( grid_abs_sub );
6862 if( tmpsub == nullptr ) {
6863 // It doesn't exist; we must generate it!
6864 dbg( DL::Info ) << "map::loadn: Missing mapbuffer data. Regenerating.";
6865
6866 // Each overmap square is two nonants; to prevent overlap, generate only at
6867 // squares divisible by 2.
6868 // TODO: fix point types
6869 const tripoint_abs_omt grid_abs_omt( sm_to_omt_copy( grid_abs_sub ) );
6870 const tripoint grid_abs_sub_rounded = omt_to_sm_copy( grid_abs_omt.raw() );
6871
6872 const oter_id terrain_type = overmap_buffer.ter( grid_abs_omt );
6873
6874 // Short-circuit if the map tile is uniform
6875 // TODO: Replace with json mapgen functions.
6876 if( terrain_type == air ) {
6877 generate_uniform( grid_abs_sub_rounded, t_open_air );
6878 } else if( terrain_type == rock ) {
6879 generate_uniform( grid_abs_sub_rounded, t_rock );
6880 } else {
6881 tinymap tmp_map;
6882 tmp_map.generate( grid_abs_sub_rounded, calendar::turn );
6883 }
6884
6885 // This is the same call to MAPBUFFER as above!
6886 tmpsub = MAPBUFFER.lookup_submap( grid_abs_sub );
6887 if( tmpsub == nullptr ) {
6888 debugmsg( "failed to generate a submap at %s", grid_abs_sub.to_string() );
6889 return;
6890 }
6891 }
6892
6893 // New submap changes the content of the map and all caches must be recalculated
6900 setsubmap( gridn, tmpsub );
6901 if( !tmpsub->active_items.empty() ) {
6902 submaps_with_active_items.emplace( grid_abs_sub );
6903 }
6904 if( tmpsub->field_count > 0 ) {
6905 get_cache( grid.z ).field_cache.set( grid.x + grid.y * MAPSIZE );
6906 }
6907 // Destroy bugged no-part vehicles
6908 auto &veh_vec = tmpsub->vehicles;
6909 for( auto iter = veh_vec.begin(); iter != veh_vec.end(); ) {
6910 vehicle *veh = iter->get();
6911 if( veh->part_count() > 0 ) {
6912 // Always fix submap coordinates for easier Z-level-related operations
6913 veh->sm_pos = grid;
6914 veh->attach();
6915 iter++;
6916 } else {
6918 if( veh->tracking_on ) {
6920 }
6921 dirty_vehicle_list.erase( veh );
6922 iter = veh_vec.erase( iter );
6923 }
6924 }
6925
6926 // Update vehicle data
6927 if( update_vehicles ) {
6928 auto &map_cache = get_cache( grid.z );
6929 for( const auto &veh : tmpsub->vehicles ) {
6930 // Only add if not tracking already.
6931 if( map_cache.vehicle_list.find( veh.get() ) == map_cache.vehicle_list.end() ) {
6932 map_cache.vehicle_list.insert( veh.get() );
6933 if( !veh->loot_zones.empty() ) {
6934 map_cache.zone_vehicles.insert( veh.get() );
6935 }
6936 add_vehicle_to_cache( veh.get() );
6937 }
6938 }
6939 }
6940
6941 actualize( grid );
6942
6943 abs_sub.z = old_abs_z;
6944}
void set_suspension_cache_dirty(const int zlev)
Definition: map.h:442
void generate(const tripoint &p, const time_point &when)
Definition: mapgen.cpp:105
void actualize(const tripoint &grid)
Fast forward a submap that has just been loading into this map.
Definition: map.cpp:7264
submap * lookup_submap(const tripoint &p)
Get a submap stored in this buffer.
Definition: mapbuffer.cpp:88
Definition: map.h:2065
std::unordered_multimap< point, zone_data > loot_zones
Definition: vehicle.h:1843
int part_count() const
Definition: vehicle.cpp:6898
void attach()
Definition: vehicle.h:764
point omt_to_sm_copy(const point &p)
static void generate_uniform(const tripoint &p, const ter_id &terrain_type)
Definition: map.cpp:6833
mapbuffer MAPBUFFER
Definition: mapbuffer.cpp:40

References abs_sub, submap::active_items, actualize(), add_vehicle_to_cache(), vehicle::attach(), dbg, debugmsg, dirty_vehicle_list, active_item_cache::empty(), level_cache::field_cache, submap::field_count, generate(), generate_uniform(), get_cache(), get_nonant(), grid, Info, mapbuffer::lookup_submap(), MAPBUFFER, MAPSIZE, omt_to_sm_copy(), overmap_buffer, vehicle::part_count(), coords::coord_point< Point, Origin, Scale >::raw(), overmapbuffer::remove_vehicle(), reset_vehicle_cache(), set_floor_cache_dirty(), set_outside_cache_dirty(), set_pathfinding_cache_dirty(), set_seen_cache_dirty(), set_suspension_cache_dirty(), set_transparency_cache_dirty(), setsubmap(), vehicle::sm_pos, sm_to_omt_copy(), submaps_with_active_items, t_open_air, t_rock, overmapbuffer::ter(), tripoint::to_string(), vehicle::tracking_on, calendar::turn, submap::vehicles, tripoint::xy(), and tripoint::z.

Referenced by load(), loadn(), and shift().

◆ make_active()

void map::make_active ( item_location loc)

Update an item's active status, for example when adding hot or perishable liquid to a container.

Definition at line 4406 of file map.cpp.

4407{
4408 item *target = loc.get_item();
4409
4410 // Trust but verify, don't let stinking callers set items active when they shouldn't be.
4411 if( !target->needs_processing() ) {
4412 return;
4413 }
4414 point l;
4415 submap *const current_submap = get_submap_at( loc.position(), l );
4416 cata::colony<item> &item_stack = current_submap->get_items( l );
4418
4419 if( current_submap->active_items.empty() ) {
4421 abs_sub.y + loc.position().y / SEEY, loc.position().z ) );
4422 }
4423 current_submap->active_items.add( *iter, l );
4424}
item * get_item()
Gets the selected item or nullptr.
tripoint position() const
Returns the position where the item is found.

References abs_sub, submap::active_items, active_item_cache::add(), active_item_cache::empty(), item_location::get_item(), submap::get_items(), item_stack::get_iterator_from_pointer(), get_submap_at(), item::needs_processing(), item_location::position(), SEEX, SEEY, submaps_with_active_items, tripoint::x, tripoint::y, and tripoint::z.

Referenced by make_active(), and liquid_handler::perform_liquid_transfer().

◆ make_rubble() [1/3]

void map::make_rubble ( const tripoint p)
inline

Definition at line 1034 of file map.h.

1034 {
1035 make_rubble( p, f_rubble, false, t_dirt, false );
1036 }

References f_rubble, make_rubble(), and t_dirt.

◆ make_rubble() [2/3]

void map::make_rubble ( const tripoint p,
const furn_id rubble_type,
bool  items 
)
inline

Definition at line 1031 of file map.h.

1031 {
1032 make_rubble( p, rubble_type, items, t_dirt, false );
1033 }

References make_rubble(), and t_dirt.

◆ make_rubble() [3/3]

void map::make_rubble ( const tripoint p,
const furn_id rubble_type,
bool  items,
const ter_id floor_type,
bool  overwrite = false 
)

Generates rubble at the given location, if overwrite is true it just writes on top of what currently exists floor_type is only used if there is a non-bashable wall at the location or with overwrite = true.

Definition at line 2493 of file map.cpp.

2495{
2496 if( overwrite ) {
2497 ter_set( p, floor_type );
2498 furn_set( p, rubble_type );
2499 } else {
2500 // First see if there is existing furniture to destroy
2501 if( is_bashable_furn( p ) ) {
2502 destroy_furn( p, true );
2503 }
2504 // Leave the terrain alone unless it interferes with furniture placement
2505 if( impassable( p ) && is_bashable_ter( p ) ) {
2506 destroy( p, true );
2507 }
2508 // Check again for new terrain after potential destruction
2509 if( impassable( p ) ) {
2510 ter_set( p, floor_type );
2511 }
2512
2513 furn_set( p, rubble_type );
2514 }
2515
2516 if( !items ) {
2517 return;
2518 }
2519
2520 //Still hardcoded, but a step up from the old stuff due to being in only one place
2521 if( rubble_type == f_wreckage ) {
2522 item chunk( "steel_chunk", calendar::turn );
2523 item scrap( "scrap", calendar::turn );
2524 add_item_or_charges( p, chunk );
2525 add_item_or_charges( p, scrap );
2526 if( one_in( 5 ) ) {
2527 item pipe( "pipe", calendar::turn );
2528 item wire( "wire", calendar::turn );
2529 add_item_or_charges( p, pipe );
2530 add_item_or_charges( p, wire );
2531 }
2532 } else if( rubble_type == f_rubble_rock ) {
2533 item rock( "rock", calendar::turn );
2534 int rock_count = rng( 1, 3 );
2535 for( int i = 0; i < rock_count; i++ ) {
2536 add_item_or_charges( p, rock );
2537 }
2538 } else if( rubble_type == f_rubble ) {
2539 item splinter( "splinter", calendar::turn );
2540 int splinter_count = rng( 2, 8 );
2541 for( int i = 0; i < splinter_count; i++ ) {
2542 add_item_or_charges( p, splinter );
2543 }
2544 spawn_item( p, itype_nail, 1, rng( 20, 50 ) );
2545 }
2546}
void destroy_furn(const tripoint &p, bool silent=false)
Keeps bashing a square until there is no more furniture.
Definition: map.cpp:3633
static const itype_id itype_nail("nail")

References add_item_or_charges(), destroy(), destroy_furn(), f_rubble, f_rubble_rock, f_wreckage, furn_set(), impassable(), is_bashable_furn(), is_bashable_ter(), itype_nail, one_in(), rng(), spawn_item(), ter_set(), and calendar::turn.

Referenced by computer_session::action_irradiator(), computer_session::action_srcf_seal(), jmapgen_make_rubble::apply(), collapse_at(), draw_lab(), draw_mine(), computer_session::failure_pump_explode(), make_rubble(), mapgen_crater(), MapExtras::mx_helicopter(), and MapExtras::mx_portal().

◆ maptile_at() [1/2]

maptile map::maptile_at ( const tripoint p)

Definition at line 206 of file map.cpp.

207{
208 if( !inbounds( p ) ) {
209 return maptile( &null_submap, point_zero );
210 }
211
212 return maptile_at_internal( p );
213}
static submap null_submap
Definition: map.cpp:195

References inbounds(), maptile_at_internal(), null_submap, and point_zero.

◆ maptile_at() [2/2]

maptile map::maptile_at ( const tripoint p) const

◆ maptile_at_internal() [1/2]

maptile map::maptile_at_internal ( const tripoint p)
private

Definition at line 223 of file map.cpp.

224{
225 point l;
226 submap *const sm = get_submap_at( p, l );
227
228 return maptile( sm, l );
229}

References get_submap_at(), and coords::sm.

◆ maptile_at_internal() [2/2]

maptile map::maptile_at_internal ( const tripoint p) const
private

Definition at line 215 of file map.cpp.

216{
217 point l;
218 submap *const sm = get_submap_at( p, l );
219
220 return maptile( sm, l );
221}

References get_submap_at(), and coords::sm.

Referenced by draw(), maptile_at(), maptile_has_bounds(), process_fields_in_submap(), route(), and spread_gas().

◆ maptile_has_bounds()

std::pair< tripoint, maptile > map::maptile_has_bounds ( const tripoint p,
bool  bounds_checked 
)
private

Definition at line 180 of file map_field.cpp.

181{
182 if( bounds_checked ) {
183 // We know that the point is in bounds
184 return {p, maptile_at_internal( p )};
185 }
186
187 return {p, maptile_at( p )};
188}

References maptile_at(), and maptile_at_internal().

Referenced by get_neighbors().

◆ max_volume()

units::volume map::max_volume ( const tripoint p)

Definition at line 4197 of file map.cpp.

4198{
4199 return i_at( p ).max_volume();
4200}
units::volume max_volume() const override
Maximum volume allowed here.
Definition: map.cpp:158

References i_at(), and map_stack::max_volume().

Referenced by advanced_inventory::print_items().

◆ mod_field_age()

time_duration map::mod_field_age ( const tripoint p,
const field_type_id type,
const time_duration offset 
)

Increment/decrement age of field entry at point.

Returns
resulting age or -1_turns if not present (does not create a new field).

Definition at line 5306 of file map.cpp.

5308{
5309 return set_field_age( p, type, offset, true );
5310}
time_duration set_field_age(const tripoint &p, const field_type_id &type, const time_duration &age, bool isoffset=false)
Set age of field entry at point.
Definition: map.cpp:5317

References set_field_age(), and type.

Referenced by game::process_artifact().

◆ mod_field_intensity()

int map::mod_field_intensity ( const tripoint p,
const field_type_id type,
int  offset 
)

Increment/decrement intensity of field entry at point, creating if not present, removing if intensity becomes 0.

Returns
resulting intensity, or 0 for not present (either removed or not created at all).

Definition at line 5312 of file map.cpp.

5313{
5314 return set_field_intensity( p, type, offset, true );
5315}
int set_field_intensity(const tripoint &p, const field_type_id &type, int new_intensity, bool isoffset=false)
Set intensity of field entry at point, creating if not present, removing if intensity becomes 0.
Definition: map.cpp:5330

References set_field_intensity(), and type.

Referenced by add_splatter(), and propagate_field().

◆ monster_in_field()

void map::monster_in_field ( monster z)
protected

Definition at line 1629 of file map_field.cpp.

1630{
1631 if( z.digging() ) {
1632 // Digging monsters are immune to fields
1633 return;
1634 }
1635 if( veh_at( z.pos() ) ) {
1636 // FIXME: Immune when in a vehicle for now.
1637 return;
1638 }
1639 field &curfield = get_field( z.pos() );
1640
1641 int dam = 0;
1642 // Iterate through all field effects on this tile.
1643 // Do not remove the field with remove_field, instead set it's intensity to 0. It will be removed
1644 // later by the field processing, which will also adjust field_count accordingly.
1645 for( auto &field_list_it : curfield ) {
1646 field_entry &cur = field_list_it.second;
1647 if( !cur.is_field_alive() ) {
1648 continue;
1649 }
1650 const field_type_id cur_field_type = cur.get_field_type();
1651 if( cur_field_type == fd_web ) {
1652 if( !z.has_flag( MF_WEBWALK ) ) {
1653 z.add_effect( effect_webbed, 1_turns, num_bp, cur.get_field_intensity() );
1654 cur.set_field_intensity( 0 );
1655 }
1656 }
1657 if( cur_field_type == fd_acid ) {
1658 if( !z.flies() ) {
1659 const int d = rng( cur.get_field_intensity(), cur.get_field_intensity() * 3 );
1660 z.deal_damage( nullptr, bodypart_id( "torso" ), damage_instance( DT_ACID, d ) );
1661 z.check_dead_state();
1662 if( d > 0 ) {
1663 z.add_effect( effect_corroding, 1_turns * rng( d / 2, d * 2 ) );
1664 }
1665 }
1666
1667 }
1668 if( cur_field_type == fd_sap ) {
1669 z.moves -= cur.get_field_intensity() * 5;
1671 }
1672 if( cur_field_type == fd_sludge ) {
1673 if( !z.digs() && !z.flies() &&
1674 !z.has_flag( MF_SLUDGEPROOF ) ) {
1675 z.moves -= cur.get_field_intensity() * 300;
1676 cur.set_field_intensity( 0 );
1677 }
1678 }
1679 if( cur_field_type == fd_fire ) {
1680 // TODO: MATERIALS Use fire resistance
1681 if( z.has_flag( MF_FIREPROOF ) || z.has_flag( MF_FIREY ) ) {
1682 return;
1683 }
1684 // TODO: Replace the section below with proper json values
1686 dam += 3;
1687 }
1688 if( z.made_of( material_id( "veggy" ) ) ) {
1689 dam += 12;
1690 }
1692 dam += 20;
1693 }
1695 dam += -20;
1696 }
1697 if( z.flies() ) {
1698 dam -= 15;
1699 }
1700 dam -= z.get_armor_type( DT_HEAT, bodypart_id( "torso" ) );
1701
1702 if( cur.get_field_intensity() == 1 ) {
1703 dam += rng( 2, 6 );
1704 } else if( cur.get_field_intensity() == 2 ) {
1705 dam += rng( 6, 12 );
1706 if( !z.flies() ) {
1707 z.moves -= 20;
1708 if( dam > 0 ) {
1709 z.add_effect( effect_onfire, 1_turns * rng( dam / 2, dam * 2 ) );
1710 }
1711 }
1712 } else if( cur.get_field_intensity() == 3 ) {
1713 dam += rng( 10, 20 );
1714 if( !z.flies() || one_in( 3 ) ) {
1715 z.moves -= 40;
1716 if( dam > 0 ) {
1717 z.add_effect( effect_onfire, 1_turns * rng( dam / 2, dam * 2 ) );
1718 }
1719 }
1720 }
1721 }
1722 if( cur_field_type == fd_smoke ) {
1723 if( !z.has_flag( MF_NO_BREATHE ) ) {
1724 if( cur.get_field_intensity() == 3 ) {
1725 z.moves -= rng( 10, 20 );
1726 }
1727 // Plants suffer from smoke even worse
1728 if( z.made_of( material_id( "veggy" ) ) ) {
1729 z.moves -= rng( 1, cur.get_field_intensity() * 12 );
1730 }
1731 }
1732
1733 }
1734 if( cur_field_type == fd_tear_gas ) {
1736 if( cur.get_field_intensity() == 3 ) {
1737 z.add_effect( effect_stunned, rng( 1_minutes, 2_minutes ) );
1738 dam += rng( 4, 10 );
1739 } else if( cur.get_field_intensity() == 2 ) {
1740 z.add_effect( effect_stunned, rng( 5_turns, 10_turns ) );
1741 dam += rng( 2, 5 );
1742 } else {
1743 z.add_effect( effect_stunned, rng( 1_turns, 5_turns ) );
1744 }
1745 if( z.made_of( material_id( "veggy" ) ) ) {
1746 z.moves -= rng( cur.get_field_intensity() * 5, cur.get_field_intensity() * 12 );
1747 dam += cur.get_field_intensity() * rng( 8, 14 );
1748 }
1749 if( z.has_flag( MF_SEES ) ) {
1750 z.add_effect( effect_blind, cur.get_field_intensity() * 8_turns );
1751 }
1752 }
1753
1754 }
1755 if( cur_field_type == fd_relax_gas ) {
1757 z.add_effect( effect_stunned, rng( cur.get_field_intensity() * 4_turns,
1758 cur.get_field_intensity() * 8_turns ) );
1759 }
1760 }
1761 if( cur_field_type == fd_dazzling ) {
1762 if( z.has_flag( MF_SEES ) && !z.has_flag( MF_ELECTRONIC ) ) {
1763 z.add_effect( effect_blind, cur.get_field_intensity() * 12_turns );
1764 z.add_effect( effect_stunned, cur.get_field_intensity() * rng( 5_turns, 12_turns ) );
1765 }
1766
1767 }
1768 if( cur_field_type == fd_toxic_gas ) {
1769 if( !z.has_flag( MF_NO_BREATHE ) ) {
1770 dam += cur.get_field_intensity();
1771 z.moves -= cur.get_field_intensity();
1772 }
1773
1774 }
1775 if( cur_field_type == fd_nuke_gas ) {
1776 if( !z.has_flag( MF_NO_BREATHE ) ) {
1777 if( cur.get_field_intensity() == 3 ) {
1778 z.moves -= rng( 60, 120 );
1779 dam += rng( 30, 50 );
1780 } else if( cur.get_field_intensity() == 2 ) {
1781 z.moves -= rng( 20, 50 );
1782 dam += rng( 10, 25 );
1783 } else {
1784 z.moves -= rng( 0, 15 );
1785 dam += rng( 0, 12 );
1786 }
1787 if( z.made_of( material_id( "veggy" ) ) ) {
1788 z.moves -= rng( cur.get_field_intensity() * 5, cur.get_field_intensity() * 12 );
1789 dam *= cur.get_field_intensity();
1790 }
1791 }
1792
1793 }
1794 if( cur_field_type == fd_flame_burst ) {
1795 // TODO: MATERIALS Use fire resistance
1796 if( z.has_flag( MF_FIREPROOF ) || z.has_flag( MF_FIREY ) ) {
1797 return;
1798 }
1800 dam += 3;
1801 }
1802 if( z.made_of( material_id( "veggy" ) ) ) {
1803 dam += 12;
1804 }
1806 dam += 50;
1807 }
1809 dam += -25;
1810 }
1811 dam += rng( 0, 8 );
1812 z.moves -= 20;
1813 }
1814 if( cur_field_type == fd_electricity ) {
1815 // We don't want to increase dam, but deal a separate hit so that it can apply effects
1816 z.deal_damage( nullptr, bodypart_id( "torso" ),
1817 damage_instance( DT_ELECTRIC, rng( 1, cur.get_field_intensity() * 3 ) ) );
1818 }
1819 if( cur_field_type == fd_fatigue ) {
1820 if( rng( 0, 2 ) < cur.get_field_intensity() ) {
1821 dam += cur.get_field_intensity();
1822 teleport::teleport( z );
1823 }
1824 }
1825 if( cur_field_type == fd_incendiary ) {
1826 // TODO: MATERIALS Use fire resistance
1827 if( z.has_flag( MF_FIREPROOF ) || z.has_flag( MF_FIREY ) ) {
1828 return;
1829 }
1831 dam += 3;
1832 }
1833 if( z.made_of( material_id( "veggy" ) ) ) {
1834 dam += 12;
1835 }
1837 dam += 20;
1838 }
1840 dam += -5;
1841 }
1842
1843 if( cur.get_field_intensity() == 1 ) {
1844 dam += rng( 2, 6 );
1845 } else if( cur.get_field_intensity() == 2 ) {
1846 dam += rng( 6, 12 );
1847 z.moves -= 20;
1848 if( !z.made_of( LIQUID ) && !z.made_of_any( Creature::cmat_flameres ) ) {
1849 z.add_effect( effect_onfire, rng( 8_turns, 12_turns ) );
1850 }
1851 } else if( cur.get_field_intensity() == 3 ) {
1852 dam += rng( 10, 20 );
1853 z.moves -= 40;
1854 if( !z.made_of( LIQUID ) && !z.made_of_any( Creature::cmat_flameres ) ) {
1855 z.add_effect( effect_onfire, rng( 12_turns, 16_turns ) );
1856 }
1857 }
1858 }
1859 if( cur_field_type == fd_fungal_haze ) {
1860 if( !z.type->in_species( FUNGUS ) &&
1861 !z.type->has_flag( MF_NO_BREATHE ) &&
1862 !z.make_fungus() ) {
1863 // Don't insta-kill jabberwocks, that's silly
1864 const int intensity = cur.get_field_intensity();
1865 z.moves -= rng( 10 * intensity, 30 * intensity );
1866 dam += rng( 0, 10 * intensity );
1867 }
1868 }
1869 if( cur_field_type == fd_fungicidal_gas ) {
1870 if( z.type->in_species( FUNGUS ) ) {
1871 const int intensity = cur.get_field_intensity();
1872 z.moves -= rng( 10 * intensity, 30 * intensity );
1873 dam += rng( 4, 7 * intensity );
1874 }
1875 }
1876 if( cur_field_type == fd_insecticidal_gas ) {
1877 if( z.type->in_species( INSECT ) || z.type->in_species( SPIDER ) ) {
1878 const int intensity = cur.get_field_intensity();
1879 z.moves -= rng( 10 * intensity, 30 * intensity );
1880 dam += rng( 4, 7 * intensity );
1881 }
1882 }
1883 }
1884
1885 if( dam > 0 ) {
1886 z.apply_damage( nullptr, bodypart_id( "torso" ), dam, true );
1887 z.check_dead_state();
1888 }
1889}
static const std::set< material_id > cmat_flammable
Definition: creature.h:477
virtual dealt_damage_instance deal_damage(Creature *source, bodypart_id bp, const damage_instance &dam)
Deals the damage via an attack.
Definition: creature.cpp:876
static const std::set< material_id > cmat_flesh
Definition: creature.h:475
int moves
Definition: creature.h:569
static const std::set< material_id > cmat_fleshnveg
Definition: creature.h:476
static const std::set< material_id > cmat_flameres
Definition: creature.h:478
bool has_flag(m_flag f) const override
Definition: monster.cpp:869
bool digs() const
Definition: monster.cpp:911
bool made_of_any(const std::set< material_id > &ms) const override
Definition: monster.cpp:963
void add_effect(const efftype_id &eff_id, const time_duration &dur, const bodypart_str_id &bp, int intensity=0, bool force=false, bool deferred=false) override
Performs any monster-specific modifications to the arguments before passing to Creature::add_effect()...
Definition: monster.cpp:1807
bool make_fungus()
Makes this monster into a fungus version Returns false if no such monster exists Returns true if mons...
Definition: monster.cpp:2599
const tripoint & pos() const override
Definition: monster.cpp:255
bool made_of(const material_id &m) const override
Definition: monster.cpp:958
const mtype * type
Definition: monster.h:478
int get_armor_type(damage_type dt, bodypart_id bp) const override
Definition: monster.cpp:1868
bool flies() const
Definition: monster.cpp:916
bool digging() const override
Definition: monster.cpp:901
@ DT_ELECTRIC
Definition: damage.h:30
@ DT_HEAT
Definition: damage.h:28
field_type_id fd_incendiary
Definition: field_type.cpp:372
field_type_id fd_toxic_gas
Definition: field_type.cpp:347
field_type_id fd_tear_gas
Definition: field_type.cpp:348
field_type_id fd_sludge
Definition: field_type.cpp:344
field_type_id fd_nuke_gas
Definition: field_type.cpp:349
field_type_id fd_dazzling
Definition: field_type.cpp:361
field_type_id fd_electricity
Definition: field_type.cpp:353
field_type_id fd_fungal_haze
Definition: field_type.cpp:374
field_type_id fd_smoke
Definition: field_type.cpp:346
field_type_id fd_sap
Definition: field_type.cpp:343
field_type_id fd_fungicidal_gas
Definition: field_type.cpp:383
field_type_id fd_acid
Definition: field_type.cpp:342
field_type_id fd_flame_burst
Definition: field_type.cpp:352
field_type_id fd_relax_gas
Definition: field_type.cpp:373
field_type_id fd_fatigue
Definition: field_type.cpp:354
field_type_id fd_insecticidal_gas
Definition: field_type.cpp:384
static const efftype_id effect_blind("blind")
static const species_id FUNGUS("FUNGUS")
static const species_id INSECT("INSECT")
static const efftype_id effect_webbed("webbed")
static const efftype_id effect_stunned("stunned")
static const species_id SPIDER("SPIDER")
static const efftype_id effect_onfire("onfire")
@ MF_SEES
Definition: mtype.h:67
@ MF_FIREY
Definition: mtype.h:103
@ MF_WEBWALK
Definition: mtype.h:85
@ MF_FIREPROOF
Definition: mtype.h:99
@ MF_SLUDGEPROOF
Definition: mtype.h:100
@ MF_ELECTRONIC
Definition: mtype.h:105
@ MF_NO_BREATHE
Definition: mtype.h:123
bool teleport(Creature &critter, int min_distance=2, int max_distance=12, bool safe=false, bool add_teleglow=true)
Teleports a creature to a tile within min_distance and max_distance tiles.
Definition: teleport.cpp:24
bool has_flag(m_flag flag) const
Definition: mtype.cpp:75
bool in_species(const species_id &spec) const
Definition: mtype.cpp:122

References monster::add_effect(), monster::apply_damage(), Creature::check_dead_state(), Creature::cmat_flameres, Creature::cmat_flammable, Creature::cmat_flesh, Creature::cmat_fleshnveg, Creature::deal_damage(), monster::digging(), monster::digs(), DT_ACID, DT_ELECTRIC, DT_HEAT, effect_blind, effect_corroding, effect_onfire, effect_stunned, effect_webbed, fd_acid, fd_dazzling, fd_electricity, fd_fatigue, fd_fire, fd_flame_burst, fd_fungal_haze, fd_fungicidal_gas, fd_incendiary, fd_insecticidal_gas, fd_nuke_gas, fd_relax_gas, fd_sap, fd_sludge, fd_smoke, fd_tear_gas, fd_toxic_gas, fd_web, monster::flies(), FUNGUS, monster::get_armor_type(), get_field(), field_entry::get_field_intensity(), field_entry::get_field_type(), monster::has_flag(), mtype::has_flag(), mtype::in_species(), INSECT, field_entry::is_field_alive(), LIQUID, monster::made_of(), monster::made_of_any(), monster::make_fungus(), MF_ELECTRONIC, MF_FIREPROOF, MF_FIREY, MF_NO_BREATHE, MF_SEES, MF_SLUDGEPROOF, MF_WEBWALK, Creature::moves, num_bp, one_in(), monster::pos(), rng(), field_entry::set_field_intensity(), SPIDER, teleport::teleport(), monster::type, and veh_at().

Referenced by creature_in_field().

◆ mop_spills()

bool map::mop_spills ( const tripoint p)

Remove moppable fields/items at this location.

Parameters
pthe location
Returns
true if anything moppable was there, false otherwise.

Definition at line 2789 of file map.cpp.

2790{
2791 bool retval = false;
2792
2793 if( !has_flag( "LIQUIDCONT", p ) && !has_flag( "SEALED", p ) ) {
2794 auto items = i_at( p );
2795 auto new_end = std::remove_if( items.begin(), items.end(), []( const item & it ) {
2796 return it.made_of( LIQUID );
2797 } );
2798 retval = new_end != items.end();
2799 while( new_end != items.end() ) {
2800 new_end = items.erase( new_end );
2801 }
2802 }
2803
2804 field &fld = field_at( p );
2805 static const std::vector<field_type_id> to_check = {
2806 fd_blood,
2814 fd_bile,
2815 fd_slime,
2816 fd_sludge
2817 };
2818 for( field_type_id fid : to_check ) {
2819 retval |= fld.remove_field( fid );
2820 }
2821
2822 if( const optional_vpart_position vp = veh_at( p ) ) {
2823 vehicle *const veh = &vp->vehicle();
2824 std::vector<int> parts_here = veh->parts_at_relative( vp->mount(), true );
2825 for( auto &elem : parts_here ) {
2826 if( veh->part( elem ).blood > 0 ) {
2827 veh->part( elem ).blood = 0;
2828 retval = true;
2829 }
2830 //remove any liquids that somehow didn't fall through to the ground
2831 vehicle_stack here = veh->get_items( elem );
2832 auto new_end = std::remove_if( here.begin(), here.end(), []( const item & it ) {
2833 return it.made_of( LIQUID );
2834 } );
2835 retval |= ( new_end != here.end() );
2836 while( new_end != here.end() ) {
2837 new_end = here.erase( new_end );
2838 }
2839 }
2840 } // if veh != 0
2841 return retval;
2842}
bool remove_field(const field_type_id &field_to_remove)
Removes the field entry with a type equal to the field_type_id parameter.
Definition: field.cpp:219
iterator erase(const_iterator it) override
Definition: vehicle.cpp:230
std::vector< int > parts_at_relative(const point &dp, bool use_cache) const
Definition: vehicle.cpp:2416
field_type_id fd_gibs_insect
Definition: field_type.cpp:365
field_type_id fd_blood_insect
Definition: field_type.cpp:363
field_type_id fd_bile
Definition: field_type.cpp:337
field_type_id fd_blood_invertebrate
Definition: field_type.cpp:364
field_type_id fd_blood_veggy
Definition: field_type.cpp:362
field_type_id fd_gibs_veggy
Definition: field_type.cpp:339
field_type_id fd_blood
Definition: field_type.cpp:336
field_type_id fd_slime
Definition: field_type.cpp:341
field_type_id fd_gibs_invertebrate
Definition: field_type.cpp:366
field_type_id fd_gibs_flesh
Definition: field_type.cpp:338

References item_stack::begin(), vehicle_part::blood, item_stack::end(), vehicle_stack::erase(), fd_bile, fd_blood, fd_blood_insect, fd_blood_invertebrate, fd_blood_veggy, fd_gibs_flesh, fd_gibs_insect, fd_gibs_invertebrate, fd_gibs_veggy, fd_slime, fd_sludge, field_at(), vehicle::get_items(), has_flag(), i_at(), vehicle::part(), vehicle::parts_at_relative(), field::remove_field(), veh_at(), and vehicle::vehicle().

◆ move_cost() [1/2]

int map::move_cost ( const point p,
const vehicle ignored_vehicle = nullptr 
) const
inline

Definition at line 607 of file map.h.

607 {
608 return move_cost( tripoint( p, abs_sub.z ), ignored_vehicle );
609 }

References abs_sub, move_cost(), and tripoint::z.

◆ move_cost() [2/2]

int map::move_cost ( const tripoint p,
const vehicle ignored_vehicle = nullptr 
) const

Calculate the cost to move past the tile at p.

The move cost is determined by various obstacles, such as terrain, vehicles and furniture.

Note
Movement costs for players and zombies both use this function.
Returns
The return value is interpreted as follows:
Move Cost Meaning
0 Impassable. Use passable/impassable to check for this.
n > 0 x*n turns to move past this

Definition at line 1775 of file map.cpp.

1776{
1777 if( !inbounds( p ) ) {
1778 return 0;
1779 }
1780
1781 const furn_t &furniture = furn( p ).obj();
1782 const ter_t &terrain = ter( p ).obj();
1783 const optional_vpart_position vp = veh_at( p );
1784 vehicle *const veh = ( !vp || &vp->vehicle() == ignored_vehicle ) ? nullptr : &vp->vehicle();
1785 const int part = veh ? vp->part_index() : -1;
1786
1787 return move_cost_internal( furniture, terrain, veh, part );
1788}
int move_cost_internal(const furn_t &furniture, const ter_t &terrain, const vehicle *veh, int vpart) const
Internal versions of public functions to avoid checking same variables multiple times.
Definition: map.cpp:1738

References furn(), furniture, inbounds(), move_cost_internal(), int_id< T >::obj(), ter(), terrain, and veh_at().

Referenced by Character::base_comfort_value(), activity_handlers::burrow_finish(), combined_movecost(), draw_mine(), game::grabbed_veh_move(), place_trap_actor::is_allowed(), is_solid_neighbor(), mine_activity(), npc::move_away_from(), move_cost(), obstacle_coverage(), passable(), activity_handlers::pickaxe_finish(), game::print_terrain_info(), reachable_flood_steps(), deploy_furn_actor::use(), and game::walk_move().

◆ move_cost_internal()

int map::move_cost_internal ( const furn_t furniture,
const ter_t terrain,
const vehicle veh,
int  vpart 
) const
private

Internal versions of public functions to avoid checking same variables multiple times.

They lack safety checks, because their callers already do those.

Definition at line 1738 of file map.cpp.

1740{
1741 if( terrain.movecost == 0 || ( furniture.id && furniture.movecost < 0 ) ) {
1742 return 0;
1743 }
1744
1745 if( veh != nullptr ) {
1746 const vpart_position vp( const_cast<vehicle &>( *veh ), vpart );
1747 if( vp.obstacle_at_part() ) {
1748 return 0;
1749 } else if( vp.part_with_feature( VPFLAG_AISLE, true ) ) {
1750 return 2;
1751 } else {
1752 return 8;
1753 }
1754 }
1755
1756 if( furniture.id ) {
1757 return std::max( terrain.movecost + furniture.movecost, 0 );
1758 }
1759
1760 return std::max( terrain.movecost, 0 );
1761}

References furniture, vpart_position::obstacle_at_part(), vpart_position::part_with_feature(), terrain, and VPFLAG_AISLE.

Referenced by move_cost(), route(), and update_pathfinding_cache().

◆ move_cost_ter_furn() [1/2]

int map::move_cost_ter_furn ( const point p) const
inline

Definition at line 624 of file map.h.

624 {
625 return move_cost_ter_furn( tripoint( p, abs_sub.z ) );
626 }
int move_cost_ter_furn(const tripoint &p) const
Similar behavior to move_cost(), but ignores vehicles.
Definition: map.cpp:1800

References abs_sub, move_cost_ter_furn(), and tripoint::z.

◆ move_cost_ter_furn() [2/2]

int map::move_cost_ter_furn ( const tripoint p) const

Similar behavior to move_cost(), but ignores vehicles.

Definition at line 1800 of file map.cpp.

1801{
1802 if( !inbounds( p ) ) {
1803 return 0;
1804 }
1805
1806 point l;
1807 submap *const current_submap = get_submap_at( p, l );
1808
1809 const int tercost = current_submap->get_ter( l ).obj().movecost;
1810 if( tercost == 0 ) {
1811 return 0;
1812 }
1813
1814 const int furncost = current_submap->get_furn( l ).obj().movecost;
1815 if( furncost < 0 ) {
1816 return 0;
1817 }
1818
1819 const int cost = tercost + furncost;
1820 return cost > 0 ? cost : 0;
1821}

References submap::get_furn(), get_submap_at(), submap::get_ter(), inbounds(), map_data_common_t::movecost, and int_id< T >::obj().

Referenced by move_cost_ter_furn(), vehicle::part_collision(), passable_ter_furn(), and vehicle_wheel_traction().

◆ move_vehicle()

vehicle * map::move_vehicle ( vehicle veh,
const tripoint dp,
const tileray facing 
)

Definition at line 516 of file map.cpp.

517{
518 if( dp == tripoint_zero ) {
519 debugmsg( "Empty displacement vector" );
520 return &veh;
521 } else if( std::abs( dp.x ) > 1 || std::abs( dp.y ) > 1 || std::abs( dp.z ) > 1 ) {
522 debugmsg( "Invalid displacement vector: %d, %d, %d", dp.x, dp.y, dp.z );
523 return &veh;
524 }
525 // Split the movement into horizontal and vertical for easier processing
526 if( dp.xy() != point_zero && dp.z != 0 ) {
527 vehicle *const new_pointer = move_vehicle( veh, tripoint( dp.xy(), 0 ), facing );
528 if( !new_pointer ) {
529 return nullptr;
530 }
531
532 vehicle *const result = move_vehicle( *new_pointer, tripoint( 0, 0, dp.z ), facing );
533 if( !result ) {
534 return nullptr;
535 }
536
537 result->is_falling = false;
538 return result;
539 }
540 const bool vertical = dp.z != 0;
541 // Ensured by the splitting above
542 assert( vertical == ( dp.xy() == point_zero ) );
543
544 const int target_z = dp.z + veh.sm_pos.z;
545 if( target_z < -OVERMAP_DEPTH || target_z > OVERMAP_HEIGHT ) {
546 return &veh;
547 }
548
549 veh.precalc_mounts( 1, veh.skidding ? veh.turn_dir : facing.dir(), veh.pivot_point() );
550
551 // cancel out any movement of the vehicle due only to a change in pivot
552 tripoint dp1 = dp - veh.pivot_displacement();
553
554 if( !vertical ) {
555 veh.adjust_zlevel( 1, dp1 );
556 }
557
558 int impulse = 0;
559
560 std::vector<veh_collision> collisions;
561
562 // Find collisions
563 // Velocity of car before collision
564 // Split into vertical and horizontal movement
565 const int &coll_velocity = vertical ? veh.vertical_velocity : veh.velocity;
566 const int velocity_before = coll_velocity;
567 if( velocity_before == 0 && !veh.is_rotorcraft() && !veh.is_flying_in_air() ) {
568 debugmsg( "%s tried to move %s with no velocity",
569 veh.name, vertical ? "vertically" : "horizontally" );
570 return &veh;
571 }
572
573 bool veh_veh_coll_flag = false;
574 // Try to collide multiple times
575 size_t collision_attempts = 10;
576 do {
577 collisions.clear();
578 veh.collision( collisions, dp1, false );
579
580 // Vehicle collisions
581 std::map<vehicle *, std::vector<veh_collision> > veh_collisions;
582 for( auto &coll : collisions ) {
583 if( coll.type != veh_coll_veh ) {
584 continue;
585 }
586
587 veh_veh_coll_flag = true;
588 // Only collide with each vehicle once
589 veh_collisions[ static_cast<vehicle *>( coll.target ) ].push_back( coll );
590 }
591
592 for( auto &pair : veh_collisions ) {
593 impulse += vehicle_vehicle_collision( veh, *pair.first, pair.second );
594 }
595
596 // Non-vehicle collisions
597 for( const auto &coll : collisions ) {
598 if( coll.type == veh_coll_veh ) {
599 continue;
600 }
601 if( coll.part > veh.part_count() ||
602 veh.part( coll.part ).removed ) {
603 continue;
604 }
605
606 const point &collision_point = veh.part( coll.part ).mount;
607 const int coll_dmg = coll.imp;
608 // Shock damage, if the target part is a rotor treat as an aimed hit.
609 if( veh.part_info( coll.part ).rotor_diameter() > 0 ) {
610 veh.damage( coll.part, coll_dmg, DT_BASH, true );
611 } else {
612 impulse += coll_dmg;
613 veh.damage( coll.part, coll_dmg, DT_BASH );
614 veh.damage_all( coll_dmg / 2, coll_dmg, DT_BASH, collision_point );
615 }
616 }
617
618 // prevent vehicle bouncing after the first collision
619 if( vertical && velocity_before < 0 && coll_velocity > 0 ) {
620 veh.vertical_velocity = 0; // also affects `coll_velocity` and thus exits the loop
621 }
622
623 } while( collision_attempts-- > 0 && coll_velocity != 0 &&
624 sgn( coll_velocity ) == sgn( velocity_before ) &&
625 !collisions.empty() && !veh_veh_coll_flag );
626
627 const int velocity_after = coll_velocity;
628 bool can_move = velocity_after != 0 && sgn( velocity_after ) == sgn( velocity_before );
629 if( dp.z != 0 && veh.is_rotorcraft() ) {
630 can_move = true;
631 }
632 units::angle coll_turn = 0_degrees;
633 if( impulse > 0 ) {
634 coll_turn = shake_vehicle( veh, velocity_before, facing.dir() );
635 veh.stop_autodriving();
636 const int volume = std::min<int>( 100, std::sqrt( impulse ) );
637 // TODO: Center the sound at weighted (by impulse) average of collisions
639 false, "smash_success", "hit_vehicle" );
640 }
641
642 if( veh_veh_coll_flag ) {
643 // Break here to let the hit vehicle move away
644 return nullptr;
645 }
646
647 // If not enough wheels, mess up the ground a bit.
648 if( !vertical && !veh.valid_wheel_config() && !veh.is_in_water() && !veh.is_flying_in_air() &&
649 dp.z == 0 ) {
650 veh.velocity += veh.velocity < 0 ? 2000 : -2000;
651 for( const auto &p : veh.get_points() ) {
652 const ter_id &pter = ter( p );
653 if( pter == t_dirt || pter == t_grass ) {
654 ter_set( p, t_dirtmound );
655 }
656 }
657 }
658
659 const units::angle last_turn_dec = 1_degrees;
660 if( veh.last_turn < 0_degrees ) {
661 veh.last_turn += last_turn_dec;
662 if( veh.last_turn > -last_turn_dec ) {
663 veh.last_turn = 0_degrees;
664 }
665 } else if( veh.last_turn > 0_degrees ) {
666 veh.last_turn -= last_turn_dec;
667 if( veh.last_turn < last_turn_dec ) {
668 veh.last_turn = 0_degrees;
669 }
670 }
671
672 Character &player_character = get_player_character();
673 const bool seen = sees_veh( player_character, veh, false );
674
675 if( can_move || ( vertical && veh.is_falling ) ) {
676 // Accept new direction
677 if( veh.skidding ) {
678 veh.face.init( veh.turn_dir );
679 } else {
680 veh.face = facing;
681 }
682
683 veh.move = facing;
684 if( coll_turn != 0_degrees ) {
685 veh.skidding = true;
686 veh.turn( coll_turn );
687 }
688 veh.on_move();
689 // Actually change position
690 displace_vehicle( veh, dp1 );
691 veh.shift_zlevel();
692 } else if( !vertical ) {
693 veh.stop();
694 }
696 // If the PC is in the currently moved vehicle, adjust the
697 // view offset.
698 if( g->u.controlling_vehicle && veh_pointer_or_null( veh_at( g->u.pos() ) ) == &veh ) {
699 g->calc_driving_offset( &veh );
700 if( veh.skidding && can_move ) {
701 // TODO: Make skid recovery in air hard
703 }
704 }
705 // Now we're gonna handle traps we're standing on (if we're still moving).
706 if( !vertical && can_move ) {
707 const auto wheel_indices = veh.wheelcache; // Don't use a reference here, it causes a crash.
708
709 // Values to deal with crushing items.
710 // The math needs to be floating-point to work, so the values might as well be.
711 const float vehicle_grounded_wheel_area = static_cast<int>( vehicle_wheel_traction( veh, true ) );
712 const float weight_to_damage_factor = 0.05; // Nobody likes a magic number.
713 const float vehicle_mass_kg = to_kilogram( veh.total_mass() );
714
715 for( auto &w : wheel_indices ) {
716 const tripoint wheel_p = veh.global_part_pos3( w );
717 if( one_in( 2 ) && displace_water( wheel_p ) ) {
718 sounds::sound( wheel_p, 4, sounds::sound_t::movement, _( "splash!" ), false,
719 "environment", "splash" );
720 }
721
722 veh.handle_trap( wheel_p, w );
723 if( !has_flag( "SEALED", wheel_p ) ) {
724 const float wheel_area = veh.part( w ).wheel_area();
725
726 // Damage is calculated based on the weight of the vehicle,
727 // The area of it's wheels, and the area of the wheel running over the items.
728 // This number is multiplied by weight_to_damage_factor to get reasonable results, damage-wise.
729 const int wheel_damage = static_cast<int>( ( ( wheel_area / vehicle_grounded_wheel_area ) *
730 vehicle_mass_kg ) * weight_to_damage_factor );
731
732 //~ %1$s: vehicle name
733 smash_items( wheel_p, wheel_damage, string_format( _( "weight of %1$s" ), veh.disp_name() ),
734 false );
735 }
736 }
737 }
738 if( veh.is_towing() ) {
739 veh.do_towing_move();
740 // veh.do_towing_move() may cancel towing, so we need to recheck is_towing here
741 if( veh.is_towing() && veh.tow_data.get_towed()->tow_cable_too_far() ) {
742 add_msg( m_info, _( "A towing cable snaps off of %s." ),
743 veh.tow_data.get_towed()->disp_name() );
744 veh.tow_data.get_towed()->invalidate_towing( true );
745 }
746 }
747 // Redraw scene, but only if the player is not engaged in an activity and
748 // the vehicle was seen before or after the move.
749 if( !player_character.activity && ( seen || sees_veh( player_character, veh, true ) ) ) {
750 g->invalidate_main_ui_adaptor();
753 }
754 return &veh;
755}
player_activity activity
Definition: character.h:1582
float vehicle_wheel_traction(const vehicle &veh, bool ignore_movement_modifiers=false) const
void smash_items(const tripoint &p, int power, const std::string &cause_message, bool do_destroy)
Tries to smash the items at the given tripoint.
Definition: map.cpp:2978
bool displace_vehicle(vehicle &veh, const tripoint &dp)
Definition: map.cpp:1114
bool displace_water(const tripoint &dp)
Definition: map.cpp:1274
units::angle shake_vehicle(vehicle &veh, int velocity_before, units::angle direction)
vehicle * move_vehicle(vehicle &veh, const tripoint &dp, const tileray &facing)
Definition: map.cpp:516
float vehicle_vehicle_collision(vehicle &veh, vehicle &veh2, const std::vector< veh_collision > &collisions)
Definition: map.cpp:757
void init(const point &ad)
Definition: tileray.cpp:27
vehicle * get_towed() const
Definition: vehicle.h:158
void damage_all(int dmg1, int dmg2, damage_type type, const point &impact)
Definition: vehicle.cpp:6265
void turn(units::angle deg)
const point & pivot_point() const
Definition: vehicle.cpp:5649
void adjust_zlevel(int idir=0, const tripoint &offset=tripoint_zero)
bool is_rotorcraft() const
is the vehicle flying? is it a rotorcraft?
Definition: vehicle.cpp:4020
std::set< tripoint > & get_points(bool force_refresh=false)
Definition: vehicle.cpp:6581
bool skidding
Definition: vehicle.h:1979
units::angle last_turn
Definition: vehicle.h:1909
void precalc_mounts(int idir, units::angle dir, const point &pivot)
Definition: vehicle.cpp:3026
bool is_towing() const
Definition: vehicle.cpp:5857
int vertical_velocity
Definition: vehicle.h:1902
int velocity
Definition: vehicle.h:1898
bool valid_wheel_config() const
Definition: vehicle.cpp:4282
units::mass total_mass() const
Definition: vehicle.cpp:3129
std::vector< int > wheelcache
Definition: vehicle.h:1798
void check_falling_or_floating()
bool is_flying_in_air() const
Definition: vehicle.cpp:4030
towing_data tow_data
Definition: vehicle.h:1924
int damage(int p, int dmg, damage_type type=DT_BASH, bool aimed=true)
Definition: vehicle.cpp:6186
bool is_in_water(bool deep_water=false) const
is the vehicle mostly in water or mostly on fairly dry land?
Definition: vehicle.cpp:4045
void possibly_recover_from_skid()
tileray move
Definition: vehicle.h:1930
void stop_autodriving(bool apply_brakes=true)
bool collision(std::vector< veh_collision > &colls, const tripoint &dp, bool just_detect, bool bash_floor=false)
bool tow_cable_too_far() const
Definition: vehicle.cpp:5986
std::string disp_name() const
void handle_trap(const tripoint &p, int part)
bool is_falling
Definition: vehicle.h:1985
void shift_zlevel()
units::angle turn_dir
Definition: vehicle.h:1907
point pivot_displacement() const
Definition: vehicle.cpp:3167
void do_towing_move()
Definition: vehicle.cpp:5758
void on_move()
Definition: vehicle.cpp:5099
int rotor_diameter() const
Definition: veh_type.cpp:908
@ m_info
Definition: enums.h:258
constexpr int sgn(const T x)
Definition: enums.h:8
static bool sees_veh(const Creature &c, vehicle &veh, bool force_recalc)
Definition: map.cpp:508
void redraw_invalidated()
Definition: ui_manager.cpp:290
quantity< int, volume_in_milliliter_tag > volume
Definition: units_volume.h:16
constexpr value_type to_kilogram(const quantity< value_type, mass_in_milligram_tag > &v)
Definition: units_mass.h:73
void refresh_display()
Make changes made to the display visible to the user immediately.
static constexpr tripoint tripoint_zero
Definition: point.h:273
int wheel_area() const
Get wheel diameter times wheel width (inches^2) or return 0 if part is not wheel.
bool removed
true if this part is removed.
Definition: vehicle.h:410
point mount
mount point: x is on the forward/backward axis, y is on the left/right axis
Definition: vehicle.h:367
@ veh_coll_veh
Definition: vehicle.h:101

References _, Character::activity, add_msg(), vehicle::adjust_zlevel(), vehicle::check_falling_or_floating(), vehicle::collision(), sounds::combat, vehicle::damage(), vehicle::damage_all(), debugmsg, tileray::dir(), vehicle::disp_name(), displace_vehicle(), displace_water(), vehicle::do_towing_move(), DT_BASH, vehicle::face, g, get_player_character(), vehicle::get_points(), towing_data::get_towed(), vehicle::global_part_pos3(), vehicle::global_pos3(), vehicle::handle_trap(), has_flag(), tileray::init(), vehicle::invalidate_towing(), vehicle::is_falling, vehicle::is_flying_in_air(), vehicle::is_in_water(), vehicle::is_rotorcraft(), vehicle::is_towing(), vehicle::last_turn, m_info, vehicle_part::mount, vehicle::move, move_vehicle(), sounds::movement, vehicle::name, vehicle::on_move(), one_in(), OVERMAP_HEIGHT, vehicle::part(), vehicle::part_count(), vehicle::part_info(), vehicle::pivot_displacement(), vehicle::pivot_point(), point_zero, vehicle::possibly_recover_from_skid(), vehicle::precalc_mounts(), ui_manager::redraw_invalidated(), refresh_display(), vehicle_part::removed, vpart_info::rotor_diameter(), sees_veh(), sgn(), shake_vehicle(), vehicle::shift_zlevel(), vehicle::skidding, vehicle::sm_pos, smash_items(), sounds::sound(), vehicle::stop(), vehicle::stop_autodriving(), string_format(), t_dirt, t_dirtmound, t_grass, ter(), ter_set(), units::to_kilogram(), vehicle::total_mass(), vehicle::tow_cable_too_far(), vehicle::tow_data, tripoint_zero, vehicle::turn(), vehicle::turn_dir, vehicle::valid_wheel_config(), veh_at(), veh_coll_veh, veh_pointer_or_null(), vehicle_vehicle_collision(), vehicle_wheel_traction(), vehicle::velocity, vehicle::vertical_velocity, vehicle_part::wheel_area(), vehicle::wheelcache, tripoint::x, tripoint::xy(), tripoint::y, and tripoint::z.

Referenced by vehicle::act_on_map(), and move_vehicle().

◆ name() [1/2]

std::string map::name ( const point p)
inline

Definition at line 813 of file map.h.

813 {
814 return name( tripoint( p, abs_sub.z ) );
815 }

References abs_sub, name(), and tripoint::z.

◆ name() [2/2]

◆ obstacle_coverage()

int map::obstacle_coverage ( const tripoint loc1,
const tripoint loc2 
) const

Returns coverage of target in relation to the observer.

Target is loc2, observer is loc1. First tile from the target is an obstacle, which has the coverage value. If there's no obstacle adjacent to the target - no coverage.

Definition at line 6183 of file map.cpp.

6184{
6185 // Can't hide if you are standing on furniture, or non-flat slowing-down terrain tile.
6186 if( furn( loc2 ).obj().id || ( move_cost( loc2 ) > 2 && !has_flag_ter( TFLAG_FLAT, loc2 ) ) ) {
6187 return 0;
6188 }
6189 const point a( std::abs( loc1.x - loc2.x ) * 2, std::abs( loc1.y - loc2.y ) * 2 );
6190 int offset = std::min( a.x, a.y ) - ( std::max( a.x, a.y ) / 2 );
6191 tripoint obstaclepos;
6192 bresenham( loc2, loc1, offset, 0, [&obstaclepos]( const tripoint & new_point ) {
6193 // Only adjacent tile between you and enemy is checked for cover.
6194 obstaclepos = new_point;
6195 return false;
6196 } );
6197 if( const auto obstacle_f = furn( obstaclepos ) ) {
6198 return obstacle_f->coverage;
6199 }
6200 if( const auto vp = veh_at( obstaclepos ) ) {
6201 if( vp->obstacle_at_part() ) {
6202 return 60;
6203 } else if( !vp->part_with_feature( VPFLAG_AISLE, true ) ) {
6204 return 45;
6205 }
6206 }
6207 return ter( obstaclepos )->coverage;
6208}
@ TFLAG_FLAT
Definition: mapdata.h:317

References a, bresenham(), map_data_common_t::coverage, furn(), has_flag_ter(), move_cost(), ter(), TFLAG_FLAT, veh_at(), VPFLAG_AISLE, tripoint::x, and tripoint::y.

Referenced by Creature::sees().

◆ obstacle_name()

std::string map::obstacle_name ( const tripoint p)

Returns the name of the obstacle at p that might be blocking movement/projectiles/etc.

Note that this only accounts for vehicles, terrain, and furniture.

Definition at line 1330 of file map.cpp.

1331{
1332 if( const cata::optional<vpart_reference> vp = veh_at( p ).obstacle_at_part() ) {
1333 return vp->info().name();
1334 }
1335 return name( p );
1336}

References name(), and veh_at().

Referenced by avatar_action::move(), and teleport::teleport().

◆ on_vehicle_moved()

void map::on_vehicle_moved ( int  smz)

Callback invoked when a vehicle has moved.

Definition at line 401 of file map.cpp.

402{
406 set_floor_cache_dirty( smz + 1 );
408}

References set_floor_cache_dirty(), set_outside_cache_dirty(), set_pathfinding_cache_dirty(), and set_transparency_cache_dirty().

Referenced by vehicle::act_on_map(), and displace_vehicle().

◆ open_door()

bool map::open_door ( const tripoint p,
bool  inside,
bool  check_only = false 
)

Definition at line 3859 of file map.cpp.

3860{
3861 const auto &ter = this->ter( p ).obj();
3862 const auto &furn = this->furn( p ).obj();
3863 if( ter.open ) {
3864 if( has_flag( "OPENCLOSE_INSIDE", p ) && !inside ) {
3865 return false;
3866 }
3867
3868 if( !check_only ) {
3869 sounds::sound( p, 6, sounds::sound_t::movement, _( "swish" ), true,
3870 "open_door", ter.id.str() );
3871 ter_set( p, ter.open );
3872
3873 if( ( g->u.has_trait( trait_id( "SCHIZOPHRENIC" ) ) || g->u.has_artifact_with( AEP_SCHIZO ) )
3874 && one_in( 50 ) && !ter.has_flag( "TRANSPARENT" ) ) {
3875 tripoint mp = p + -2 * g->u.pos().xy() + tripoint( 2 * p.x, 2 * p.y, p.z );
3876 g->spawn_hallucination( mp );
3877 }
3878 }
3879
3880 return true;
3881 } else if( furn.open ) {
3882 if( has_flag( "OPENCLOSE_INSIDE", p ) && !inside ) {
3883 return false;
3884 }
3885
3886 if( !check_only ) {
3887 sounds::sound( p, 6, sounds::sound_t::movement, _( "swish" ), true,
3888 "open_door", furn.id.str() );
3889 furn_set( p, furn.open );
3890 }
3891
3892 return true;
3893 } else if( const optional_vpart_position vp = veh_at( p ) ) {
3894 int openable = vp->vehicle().next_part_to_open( vp->part_index(), true );
3895 if( openable >= 0 ) {
3896 if( !check_only ) {
3897 if( !vp->vehicle().handle_potential_theft( dynamic_cast<player &>( g->u ) ) ) {
3898 return false;
3899 }
3900 vp->vehicle().open_all_at( openable );
3901 }
3902
3903 return true;
3904 }
3905
3906 return false;
3907 }
3908
3909 return false;
3910}
@ AEP_SCHIZO
Definition: enums.h:128

References _, AEP_SCHIZO, furn(), furn_set(), g, has_flag(), int_id< T >::id(), sounds::movement, int_id< T >::obj(), one_in(), sounds::sound(), string_id< T >::str(), ter(), ter_set(), veh_at(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by can_interact_at(), npc::can_open_door(), iexamine::door_peephole(), monster::move(), avatar_action::move(), npc::move_to(), open(), and rate_location().

◆ operator=() [1/2]

map & map::operator= ( const map )
delete

◆ operator=() [2/2]

map & map::operator= ( map &&  )
default

◆ partial_con_at()

partial_con * map::partial_con_at ( const tripoint p)

Definition at line 5131 of file map.cpp.

5132{
5133 if( !inbounds( p ) ) {
5134 return nullptr;
5135 }
5136 point l;
5137 submap *const current_submap = get_submap_at( p, l );
5138 auto it = current_submap->partial_constructions.find( tripoint( l, p.z ) );
5139 if( it != current_submap->partial_constructions.end() ) {
5140 return &it->second;
5141 }
5142 return nullptr;
5143}
std::map< tripoint, partial_con > partial_constructions
Definition: submap.h:248

References get_submap_at(), inbounds(), submap::partial_constructions, and tripoint::z.

Referenced by activity_handlers::build_do_turn(), can_do_activity_there(), complete_construction(), generic_multi_activity_check_requirement(), generic_multi_activity_do(), generic_multi_activity_locations(), player_activity::get_progress_message(), place_construction(), game::print_trap_info(), and iexamine::trap().

◆ partial_con_remove()

void map::partial_con_remove ( const tripoint p)

Definition at line 5145 of file map.cpp.

5146{
5147 if( !inbounds( p ) ) {
5148 return;
5149 }
5150 point l;
5151 submap *const current_submap = get_submap_at( p, l );
5152 current_submap->partial_constructions.erase( tripoint( l, p.z ) );
5153}

References get_submap_at(), inbounds(), submap::partial_constructions, and tripoint::z.

Referenced by complete_construction(), and iexamine::trap().

◆ partial_con_set()

void map::partial_con_set ( const tripoint p,
const partial_con con 
)

Definition at line 5155 of file map.cpp.

5156{
5157 if( !inbounds( p ) ) {
5158 return;
5159 }
5160 point l;
5161 submap *const current_submap = get_submap_at( p, l );
5162 if( !current_submap->partial_constructions.emplace( tripoint( l, p.z ), con ).second ) {
5163 debugmsg( "set partial con on top of terrain which already has a partial con" );
5164 }
5165}

References debugmsg, get_submap_at(), inbounds(), submap::partial_constructions, and tripoint::z.

Referenced by construction_activity(), and place_construction().

◆ passable() [1/2]

bool map::passable ( const point p) const
inline

Definition at line 615 of file map.h.

615 {
616 return passable( tripoint( p, abs_sub.z ) );
617 }

References abs_sub, passable(), and tripoint::z.

◆ passable() [2/2]

◆ passable_ter_furn()

bool map::passable_ter_furn ( const tripoint p) const

Definition at line 1828 of file map.cpp.

1829{
1830 return move_cost_ter_furn( p ) != 0;
1831}

References move_cost_ter_furn().

Referenced by impassable_ter_furn(), and avatar_action::move().

◆ pl_line_of_sight()

bool map::pl_line_of_sight ( const tripoint t,
int  max_range 
) const

Uses the map cache to tell if the player could see the given square.

pl_sees implies pl_line_of_sight Used for infrared.

Definition at line 764 of file lightmap.cpp.

765{
766 if( !inbounds( t ) ) {
767 return false;
768 }
769
770 if( max_range >= 0 && square_dist( t, g->u.pos() ) > max_range ) {
771 // Out of range!
772 return false;
773 }
774
775 const auto &map_cache = get_cache_ref( t.z );
776 // Any epsilon > 0 is fine - it means lightmap processing visited the point
777 return map_cache.seen_cache[t.x][t.y] > 0.0f ||
778 map_cache.camera_cache[t.x][t.y] > 0.0f;
779}

References g, get_cache_ref(), inbounds(), square_dist(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by get_heat_radiation(), and Character::sees_with_infrared().

◆ pl_sees()

bool map::pl_sees ( const tripoint t,
int  max_range 
) const

Whether the player character (g->u) can see the given square (local map coordinates).

This only checks the transparency of the path to the target, the light level is not checked.

Parameters
tTarget point to look at
max_rangeAll squares that are further away than this are invisible. Ignored if smaller than 0.

Definition at line 746 of file lightmap.cpp.

747{
748 if( !inbounds( t ) ) {
749 return false;
750 }
751
752 if( max_range >= 0 && square_dist( t, g->u.pos() ) > max_range ) {
753 return false; // Out of range!
754 }
755
756 const auto &map_cache = get_cache_ref( t.z );
757 const apparent_light_info a = apparent_light_helper( map_cache, t );
758 const float light_at_player = map_cache.lm[g->u.posx()][g->u.posy()].max();
759 return !a.obstructed &&
760 ( a.apparent_light >= g->u.get_vision_threshold( light_at_player ) ||
761 map_cache.sm[t.x][t.y] > 0.0 );
762}

References a, apparent_light_helper(), g, get_cache_ref(), inbounds(), square_dist(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by computer_session::action_irradiator(), sounds::process_sound_markers(), and Character::sees().

◆ place_gas_pump() [1/2]

void map::place_gas_pump ( const point p,
int  charges 
)

Definition at line 5447 of file mapgen.cpp.

5448{
5449 place_gas_pump( p, charges, one_in( 4 ) ? "diesel" : "gasoline" );
5450}
void place_gas_pump(const point &p, int charges, const std::string &fuel_type)
Definition: mapgen.cpp:5439

References one_in(), and place_gas_pump().

◆ place_gas_pump() [2/2]

void map::place_gas_pump ( const point p,
int  charges,
const std::string &  fuel_type 
)

Definition at line 5439 of file mapgen.cpp.

5440{
5441 item fuel( fuel_type, calendar::start_of_cataclysm );
5442 fuel.charges = charges;
5443 add_item( p, fuel );
5444 ter_set( p, ter_id( fuel.fuel_pump_terrain() ) );
5445}

References add_item(), item::charges, item::fuel_pump_terrain(), calendar::start_of_cataclysm, ter_id, and ter_set().

Referenced by jmapgen_gaspump::apply(), mapgen_tutorial(), and place_gas_pump().

◆ place_items() [1/2]

std::vector< item * > map::place_items ( const item_group_id loc,
int  chance,
const point p1,
const point p2,
bool  ongrass,
const time_point turn,
int  magazine = 0,
int  ammo = 0 
)
inline

Definition at line 1337 of file map.h.

1339 {
1340 return place_items( loc, chance, tripoint( p1, abs_sub.z ), tripoint( p2, abs_sub.z ), ongrass,
1341 turn, magazine, ammo );
1342 }

References abs_sub, place_items(), calendar::turn, and tripoint::z.

◆ place_items() [2/2]

std::vector< item * > map::place_items ( const item_group_id loc,
int  chance,
const tripoint p1,
const tripoint p2,
bool  ongrass,
const time_point turn,
int  magazine = 0,
int  ammo = 0 
)

Place items from item group in the rectangle f - t.

Several items may be spawned on different places. Several items may spawn at once (at one place) when the item group says so (uses item_group::items_from which may return several items at once).

Parameters
locCurrent location of items to be placed
chanceChance for more items. A chance of 100 creates 1 item all the time, otherwise it's the chance that more items will be created (place items until the random roll with that chance fails). The chance is used for the first item as well, so it may not spawn an item at all. Values <= 0 or > 100 are invalid.
p1One corner of rectangle in which to spawn items
p2Second corner of rectangle in which to spawn items
ongrassIf false the items won't spawn on flat terrain (grass, floor, ...).
turnThe birthday that the created items shall have.
magazinepercentage chance item will contain the default magazine
ammopercentage chance item will be filled with default ammo
Returns
vector containing all placed items

Definition at line 5513 of file mapgen.cpp.

5517{
5518 // TODO: implement for 3D
5519 std::vector<item *> res;
5520
5521 if( chance > 100 || chance <= 0 ) {
5522 debugmsg( "map::place_items() called with an invalid chance (%d)", chance );
5523 return res;
5524 }
5525 if( !item_group::group_is_defined( loc ) ) {
5526 // TODO: fix point types
5528 const oter_id &oid = overmap_buffer.ter( omt );
5529 debugmsg( "place_items: invalid item group '%s', om_terrain = '%s' (%s)",
5530 loc.c_str(), oid.id().c_str(), oid->get_mapgen_id().c_str() );
5531 return res;
5532 }
5533
5534 const float spawn_rate = get_option<float>( "ITEM_SPAWNRATE" );
5535 int spawn_count = roll_remainder( chance * spawn_rate / 100.0f );
5536 for( int i = 0; i < spawn_count; i++ ) {
5537 // Might contain one item or several that belong together like guns & their ammo
5538 int tries = 0;
5539 auto is_valid_terrain = [this, ongrass]( const point & p ) {
5540 auto &terrain = ter( p ).obj();
5541 return terrain.movecost == 0 &&
5542 !terrain.has_flag( "PLACE_ITEM" ) &&
5543 !ongrass &&
5544 !terrain.has_flag( "FLAT" );
5545 };
5546
5547 point p;
5548 do {
5549 p.x = rng( p1.x, p2.x );
5550 p.y = rng( p1.y, p2.y );
5551 tries++;
5552 } while( is_valid_terrain( p ) && tries < 20 );
5553 if( tries < 20 ) {
5554 auto put = put_items_from_loc( loc, tripoint( p, abs_sub.z ), turn );
5555 res.insert( res.end(), put.begin(), put.end() );
5556 }
5557 }
5558 for( auto e : res ) {
5559 if( e->is_tool() || e->is_gun() || e->is_magazine() ) {
5560 if( rng( 0, 99 ) < magazine && !e->magazine_integral() && !e->magazine_current() ) {
5561 e->put_in( item( e->magazine_default(), e->birthday() ) );
5562 }
5563 if( rng( 0, 99 ) < ammo && e->ammo_remaining() == 0 ) {
5564 e->ammo_set( e->ammo_default(), e->ammo_capacity() );
5565 }
5566 }
5567 }
5568 return res;
5569}
constexpr scale omt
Definition: coordinates.h:32
bool group_is_defined(const item_group_id &group_id)
Check whether an item group of the given id exists.
Definition: item_group.cpp:603

References abs_sub, string_id< T >::c_str(), debugmsg, get_abs_sub(), oter_t::get_mapgen_id(), item_group::group_is_defined(), int_id< T >::id(), int_id< T >::obj(), coords::omt, overmap_buffer, put_items_from_loc(), rng(), roll_remainder(), sm_to_omt_copy(), ter(), overmapbuffer::ter(), terrain, calendar::turn, point::x, tripoint::x, point::y, tripoint::y, and tripoint::z.

Referenced by jmapgen_item_group::apply(), draw_lab(), draw_mine(), draw_office_tower(), draw_slimepit(), mapgen_ants_food(), mapgen_ants_generic(), mapgen_ants_larvae(), mapgen_ants_queen(), mapgen_cavern(), mapgen_crater(), mapgen_field(), mapgen_forest(), mapgen_forest_trail_curved(), mapgen_forest_trail_four_way(), mapgen_forest_trail_straight(), mapgen_forest_trail_tee(), mapgen_highway(), mapgen_hive(), mapgen_parking_lot(), mapgen_road(), mapgen_sewer_curved(), mapgen_sewer_four_way(), mapgen_sewer_straight(), mapgen_sewer_tee(), MapExtras::mx_collegekids(), MapExtras::mx_drugdeal(), MapExtras::mx_house_spider(), MapExtras::mx_house_wasp(), MapExtras::mx_military(), MapExtras::mx_minefield(), MapExtras::mx_roadblock(), MapExtras::mx_roadworks(), MapExtras::mx_science(), MapExtras::mx_supplydrop(), place_items(), place_vending(), mission_start::ranch_nurse_8(), mission_start::ranch_scavenger_1(), mission_start::ranch_scavenger_2(), mission_start::ranch_scavenger_3(), and science_room().

◆ place_npc()

character_id map::place_npc ( const point p,
const string_id< npc_template > &  type,
bool  force = false 
)

Definition at line 5480 of file mapgen.cpp.

5481{
5482 if( !force && !get_option<bool>( "STATIC_NPC" ) ) {
5483 return character_id(); //Do not generate an npc.
5484 }
5485 shared_ptr_fast<npc> temp = make_shared_fast<npc>();
5486 temp->normalize();
5487 temp->load_npc_template( type );
5488 temp->spawn_at_precise( { abs_sub.xy() }, { p, abs_sub.z } );
5489 temp->toggle_trait( trait_NPC_STATIC_NPC );
5490 overmap_buffer.insert_npc( temp );
5491 return temp->getID();
5492}
void insert_npc(const shared_ptr_fast< npc > &who)
Adds the npc to an overmap ( based on the npcs current location ) and stores it there.
static const trait_id trait_NPC_STATIC_NPC("NPC_STATIC_NPC")
std::shared_ptr< T > shared_ptr_fast
Definition: memory_fast.h:16

References abs_sub, character_id, overmapbuffer::insert_npc(), overmap_buffer, trait_NPC_STATIC_NPC, type, tripoint::xy(), and tripoint::z.

Referenced by jmapgen_npc::apply(), mapgen_hive(), MapExtras::mx_bandits_block(), MapExtras::mx_looters(), MapExtras::mx_marloss_pilgrimage(), mission_start::ranch_nurse_9(), and place_npc_iuse::use().

◆ place_spawns()

void map::place_spawns ( const mongroup_id group,
int  chance,
const point p1,
const point p2,
float  density,
bool  individual = false,
bool  friendly = false,
const std::string &  name = "NONE",
int  mission_id = -1 
)

Definition at line 5389 of file mapgen.cpp.

5392{
5393 if( !group.is_valid() ) {
5394 // TODO: fix point types
5396 const oter_id &oid = overmap_buffer.ter( omt );
5397 debugmsg( "place_spawns: invalid mongroup '%s', om_terrain = '%s' (%s)", group.c_str(),
5398 oid.id().c_str(), oid->get_mapgen_id().c_str() );
5399 return;
5400 }
5401
5402 // Set chance to be 1 or less to guarantee spawn, else set higher than 1
5403 if( !one_in( chance ) ) {
5404 return;
5405 }
5406
5407 float spawn_density = 1.0f;
5409 spawn_density = get_option< float >( "SPAWN_ANIMAL_DENSITY" );
5410 } else {
5411 spawn_density = get_option< float >( "SPAWN_DENSITY" );
5412 }
5413
5414 float multiplier = density * spawn_density;
5415 // Only spawn 1 creature if individual flag set, else scale by density
5416 float thenum = individual ? 1 : ( multiplier * rng_float( 10.0f, 50.0f ) );
5417 int num = roll_remainder( thenum );
5418
5419 // GetResultFromGroup decrements num
5420 while( num > 0 ) {
5421 int tries = 10;
5422 point p;
5423
5424 // Pick a spot for the spawn
5425 do {
5426 p.x = rng( p1.x, p2.x );
5427 p.y = rng( p1.y, p2.y );
5428 tries--;
5429 } while( impassable( p ) && tries > 0 );
5430
5431 // Pick a monster type
5433
5434 add_spawn( spawn_details.name, spawn_details.pack_size, { p, abs_sub.z },
5435 friendly, -1, mission_id, name );
5436 }
5437}
group
Definition: sounds.h:125

References add_spawn(), string_id< T >::c_str(), debugmsg, friendly, get_abs_sub(), oter_t::get_mapgen_id(), MonsterGroupManager::GetResultFromGroup(), int_id< T >::id(), impassable(), MonsterGroupManager::is_animal(), name(), MonsterGroupResult::name, num, coords::omt, one_in(), overmap_buffer, MonsterGroupResult::pack_size, rng(), rng_float(), roll_remainder(), sm_to_omt_copy(), overmapbuffer::ter(), point::x, and point::y.

Referenced by add_monsters(), jmapgen_monster_group::apply(), create_anomaly(), draw_lab(), draw_mine(), draw_office_tower(), draw_slimepit(), draw_temple(), draw_triffid(), mapgen_road(), MapExtras::mx_collegekids(), MapExtras::mx_corpses(), MapExtras::mx_drugdeal(), MapExtras::mx_military(), MapExtras::mx_pond(), MapExtras::mx_portal(), MapExtras::mx_portal_in(), MapExtras::mx_science(), and science_room().

◆ place_toilet()

void map::place_toilet ( const point p,
int  charges = 6 * 4 
)

Definition at line 5452 of file mapgen.cpp.

5453{
5454 item water( "water", calendar::start_of_cataclysm );
5455 water.charges = charges;
5456 add_item( p, water );
5457 furn_set( p, f_toilet );
5458}

References add_item(), item::charges, f_toilet, furn_set(), and calendar::start_of_cataclysm.

Referenced by jmapgen_toilet::apply(), and mapf::formatted_set_simple().

◆ place_vending()

void map::place_vending ( const point p,
const item_group_id type,
bool  reinforced = false 
)

Definition at line 5460 of file mapgen.cpp.

5461{
5462 if( reinforced ) {
5464 place_items( type, 100, p, p, false, calendar::start_of_cataclysm );
5465 } else {
5466 if( one_in( 2 ) ) {
5467 furn_set( p, f_vending_o );
5468 for( const auto &loc : points_in_radius( { p, abs_sub.z }, 1 ) ) {
5469 if( one_in( 4 ) ) {
5470 spawn_item( loc, "glass_shard", rng( 1, 2 ) );
5471 }
5472 }
5473 } else {
5474 furn_set( p, f_vending_c );
5475 place_items( type, 100, p, p, false, calendar::start_of_cataclysm );
5476 }
5477 }
5478}
furn_id f_vending_o
Definition: mapdata.cpp:1109
furn_id f_vending_reinforced
Definition: mapdata.cpp:1132
furn_id f_vending_c
Definition: mapdata.cpp:1109

References abs_sub, f_vending_c, f_vending_o, f_vending_reinforced, furn_set(), one_in(), place_items(), points_in_radius(), rng(), spawn_item(), calendar::start_of_cataclysm, type, and tripoint::z.

Referenced by jmapgen_vending_machine::apply().

◆ player_in_field()

void map::player_in_field ( player u)
protected

Definition at line 1221 of file map_field.cpp.

1222{
1223 // A copy of the current field for reference. Do not add fields to it, use map::add_field
1224 field &curfield = get_field( u.pos() );
1225 // Are we inside?
1226 bool inside = false;
1227 // If we are in a vehicle figure out if we are inside (reduces effects usually)
1228 // and what part of the vehicle we need to deal with.
1229 if( u.in_vehicle ) {
1230 if( const optional_vpart_position vp = veh_at( u.pos() ) ) {
1231 inside = vp->is_inside();
1232 }
1233 }
1234
1235 // Iterate through all field effects on this tile.
1236 // Do not remove the field with remove_field, instead set it's intensity to 0. It will be removed
1237 // later by the field processing, which will also adjust field_count accordingly.
1238 for( auto &field_list_it : curfield ) {
1239 field_entry &cur = field_list_it.second;
1240 if( !cur.is_field_alive() ) {
1241 continue;
1242 }
1243
1244 // Do things based on what field effect we are currently in.
1245 const field_type_id ft = cur.get_field_type();
1246 if( ft == fd_web ) {
1247 // If we are in a web, can't walk in webs or are in a vehicle, get webbed maybe.
1248 // Moving through multiple webs stacks the effect.
1249 if( !u.has_trait( trait_WEB_WALKER ) && !u.in_vehicle ) {
1250 // Between 5 and 15 minus your current web level.
1251 u.add_effect( effect_webbed, 1_turns, num_bp, cur.get_field_intensity() );
1252 // It is spent.
1253 cur.set_field_intensity( 0 );
1254 continue;
1255 // If you are in a vehicle destroy the web.
1256 // It should of been destroyed when you ran over it anyway.
1257 } else if( u.in_vehicle ) {
1258 cur.set_field_intensity( 0 );
1259 continue;
1260 }
1261 }
1262 if( ft == fd_acid ) {
1263 // Assume vehicles block acid damage entirely,
1264 // you're certainly not standing in it.
1265 if( !u.in_vehicle && !u.has_trait( trait_ACIDPROOF ) ) {
1266 int total_damage = 0;
1267 total_damage += burn_body_part( u, cur, bp_foot_l, 2 );
1268 total_damage += burn_body_part( u, cur, bp_foot_r, 2 );
1269 const bool on_ground = u.is_on_ground();
1270 if( on_ground ) {
1271 // Apply the effect to the remaining body parts
1272 total_damage += burn_body_part( u, cur, bp_leg_l, 2 );
1273 total_damage += burn_body_part( u, cur, bp_leg_r, 2 );
1274 total_damage += burn_body_part( u, cur, bp_hand_l, 2 );
1275 total_damage += burn_body_part( u, cur, bp_hand_r, 2 );
1276 total_damage += burn_body_part( u, cur, bp_torso, 2 );
1277 // Less arms = less ability to keep upright
1278 if( ( !u.has_two_arms() && one_in( 4 ) ) || one_in( 2 ) ) {
1279 total_damage += burn_body_part( u, cur, bp_arm_l, 1 );
1280 total_damage += burn_body_part( u, cur, bp_arm_r, 1 );
1281 total_damage += burn_body_part( u, cur, bp_head, 1 );
1282 }
1283 }
1284
1285 if( on_ground && total_damage > 0 ) {
1286 u.add_msg_player_or_npc( m_bad, _( "The acid burns your body!" ),
1287 _( "The acid burns <npcname>s body!" ) );
1288 } else if( total_damage > 0 ) {
1289 u.add_msg_player_or_npc( m_bad, _( "The acid burns your legs and feet!" ),
1290 _( "The acid burns <npcname>s legs and feet!" ) );
1291 } else if( on_ground ) {
1292 u.add_msg_if_player( m_warning, _( "You're lying in a pool of acid" ) );
1293 } else {
1294 u.add_msg_if_player( m_warning, _( "You're standing in a pool of acid" ) );
1295 }
1296
1297 u.check_dead_state();
1298 }
1299 }
1300 if( ft == fd_sap ) {
1301 // Sap does nothing to cars.
1302 if( !u.in_vehicle ) {
1303 // Use up sap.
1305 }
1306 }
1307 if( ft == fd_sludge ) {
1308 // Sludge is on the ground, but you are above the ground when boarded on a vehicle
1309 if( !u.in_vehicle ) {
1310 u.add_msg_if_player( m_bad, _( "The sludge is thick and sticky. You struggle to pull free." ) );
1311 u.moves -= cur.get_field_intensity() * 300;
1312 cur.set_field_intensity( 0 );
1313 }
1314 }
1315 if( ft == fd_fire ) {
1316 // Heatsink or suit prevents ALL fire damage.
1318
1319 // To modify power of a field based on... whatever is relevant for the effect.
1320 int adjusted_intensity = cur.get_field_intensity();
1321 // Burn the player. Less so if you are in a car or ON a car.
1322 if( u.in_vehicle ) {
1323 if( inside ) {
1324 adjusted_intensity -= 2;
1325 } else {
1326 adjusted_intensity -= 1;
1327 }
1328 }
1329
1330 if( adjusted_intensity >= 1 ) {
1331 // Burn message by intensity
1332 static const std::array<std::string, 4> player_burn_msg = { {
1333 translate_marker( "You burn your legs and feet!" ),
1334 translate_marker( "You're burning up!" ),
1335 translate_marker( "You're set ablaze!" ),
1336 translate_marker( "Your whole body is burning!" )
1337 }
1338 };
1339 static const std::array<std::string, 4> npc_burn_msg = { {
1340 translate_marker( "<npcname> burns their legs and feet!" ),
1341 translate_marker( "<npcname> is burning up!" ),
1342 translate_marker( "<npcname> is set ablaze!" ),
1343 translate_marker( "<npcname>s whole body is burning!" )
1344 }
1345 };
1346 static const std::array<std::string, 4> player_warn_msg = { {
1347 translate_marker( "You're standing in a fire!" ),
1348 translate_marker( "You're waist-deep in a fire!" ),
1349 translate_marker( "You're surrounded by raging fire!" ),
1350 translate_marker( "You're lying in fire!" )
1351 }
1352 };
1353
1354 const int burn_min = adjusted_intensity;
1355 const int burn_max = 3 * adjusted_intensity + 3;
1356 std::list<bodypart_id> parts_burned;
1357 int msg_num = adjusted_intensity - 1;
1358 if( !u.is_on_ground() ) {
1359 switch( adjusted_intensity ) {
1360 case 3:
1361 parts_burned.push_back( bodypart_id( "hand_l" ) );
1362 parts_burned.push_back( bodypart_id( "hand_r" ) );
1363 parts_burned.push_back( bodypart_id( "arm_l" ) );
1364 parts_burned.push_back( bodypart_id( "arm_r" ) );
1365 /* fallthrough */
1366 case 2:
1367 parts_burned.push_back( bodypart_id( "torso" ) );
1368 /* fallthrough */
1369 case 1:
1370 parts_burned.push_back( bodypart_id( "foot_l" ) );
1371 parts_burned.push_back( bodypart_id( "foot_r" ) );
1372 parts_burned.push_back( bodypart_id( "leg_l" ) );
1373 parts_burned.push_back( bodypart_id( "leg_r" ) );
1374 }
1375 } else {
1376 // Lying in the fire is BAAAD news, hits every body part.
1377 msg_num = 3;
1378 const std::vector<bodypart_id> &all_parts = u.get_all_body_parts();
1379 // HACK: Skip num_bp part
1380 for( auto bp : all_parts ) {
1381 if( bp->token != num_bp ) {
1382 parts_burned.push_back( bp );
1383 }
1384 }
1385 }
1386
1387 int total_damage = 0;
1388 for( const bodypart_id part_burned : parts_burned ) {
1389 const dealt_damage_instance dealt = u.deal_damage( nullptr, part_burned,
1390 damage_instance( DT_HEAT, rng( burn_min, burn_max ) ) );
1391 total_damage += dealt.type_damage( DT_HEAT );
1392 }
1393 if( total_damage > 0 ) {
1394 u.add_msg_player_or_npc( m_bad, _( player_burn_msg[msg_num] ), _( npc_burn_msg[msg_num] ) );
1395 } else {
1396 u.add_msg_if_player( m_warning, _( player_warn_msg[msg_num] ) );
1397 }
1398 u.check_dead_state();
1399 }
1400 }
1401
1402 }
1403 if( ft == fd_tear_gas ) {
1404 // Tear gas will both give you teargas disease and/or blind you.
1405 if( ( cur.get_field_intensity() > 1 || !one_in( 3 ) ) && ( !inside || one_in( 3 ) ) ) {
1406 u.add_env_effect( effect_teargas, bp_mouth, 5, 20_seconds );
1407 }
1408 if( cur.get_field_intensity() > 1 && ( !inside || one_in( 3 ) ) ) {
1409 u.add_env_effect( effect_blind, bp_eyes, cur.get_field_intensity() * 2, 10_seconds );
1410 }
1411 }
1412 if( ft == fd_fungal_haze ) {
1413 if( !u.has_trait( trait_M_IMMUNE ) && ( !inside || one_in( 4 ) ) ) {
1414 u.add_env_effect( effect_fungus, bp_mouth, 4, 10_minutes, num_bp );
1415 u.add_env_effect( effect_fungus, bp_eyes, 4, 10_minutes, num_bp );
1416 }
1417 }
1418 if( ft == fd_dazzling ) {
1419 if( cur.get_field_intensity() > 1 || one_in( 5 ) ) {
1420 u.add_env_effect( effect_blind, bp_eyes, 10, 10_turns );
1421 } else {
1422 u.add_env_effect( effect_blind, bp_eyes, 2, 2_turns );
1423 }
1424 }
1425
1426 if( cur.extra_radiation_min() > 0 ) {
1427 // Get irradiated by the nuclear fallout.
1428 const float rads = rng( cur.extra_radiation_min() + 1,
1429 cur.extra_radiation_max() * ( cur.extra_radiation_max() + 1 ) );
1430 const bool rad_proof = !u.irradiate( rads );
1431 // TODO: Reduce damage for rad resistant?
1432 if( cur.radiation_hurt_damage_min() > 0 && !rad_proof ) {
1434 u.hurtall( rng( cur.radiation_hurt_damage_min(), cur.radiation_hurt_damage_max() ), nullptr );
1435 }
1436 }
1437 if( ft == fd_flame_burst ) {
1438 // A burst of flame? Only hits the legs and torso.
1439 if( !inside ) {
1440 // Fireballs can't touch you inside a car.
1441 // Heatsink or suit stops fire.
1442 if( !u.has_active_bionic( bio_heatsink ) &&
1444 u.add_msg_player_or_npc( m_bad, _( "You're torched by flames!" ),
1445 _( "<npcname> is torched by flames!" ) );
1446 u.deal_damage( nullptr, bodypart_id( "leg_l" ), damage_instance( DT_HEAT, rng( 2, 6 ) ) );
1447 u.deal_damage( nullptr, bodypart_id( "leg_r" ), damage_instance( DT_HEAT, rng( 2, 6 ) ) );
1448 u.deal_damage( nullptr, bodypart_id( "torso" ), damage_instance( DT_HEAT, rng( 4, 9 ) ) );
1449 u.check_dead_state();
1450 } else {
1451 u.add_msg_player_or_npc( _( "These flames do not burn you." ),
1452 _( "Those flames do not burn <npcname>." ) );
1453 }
1454 }
1455 }
1456 if( ft == fd_electricity ) {
1457 // Small universal damage based on intensity, only if not electroproofed.
1458 if( !u.is_elec_immune() ) {
1459 int total_damage = 0;
1460 for( size_t i = 0; i < num_hp_parts; i++ ) {
1461 const bodypart_id bp = convert_bp( player::hp_to_bp( static_cast<hp_part>( i ) ) ).id();
1462 const int dmg = rng( 1, cur.get_field_intensity() );
1463 total_damage += u.deal_damage( nullptr, bp, damage_instance( DT_ELECTRIC, dmg ) ).total_damage();
1464 }
1465
1466 if( total_damage > 0 ) {
1468 u.add_msg_player_or_npc( m_bad, _( "You're painfully electrocuted!" ),
1469 _( "<npcname> is shocked!" ) );
1470 u.mod_pain( total_damage / 2 );
1471 } else {
1472 u.add_msg_player_or_npc( m_bad, _( "You're shocked!" ), _( "<npcname> is shocked!" ) );
1473 }
1474 } else {
1475 u.add_msg_player_or_npc( _( "The electric cloud doesn't affect you." ),
1476 _( "The electric cloud doesn't seem to affect <npcname>." ) );
1477 }
1478 }
1479 }
1480 if( ft == fd_fatigue ) {
1481 // Assume the rift is on the ground for now to prevent issues with the player being unable access vehicle controls on the same tile due to teleportation.
1482 if( !u.in_vehicle ) {
1483 // Teleports you... somewhere.
1484 if( rng( 0, 2 ) < cur.get_field_intensity() && u.is_player() ) {
1485 add_msg( m_bad, _( "You're violently teleported!" ) );
1486 u.hurtall( cur.get_field_intensity(), nullptr );
1487 teleport::teleport( u );
1488 }
1489 }
1490 }
1491 // Why do these get removed???
1492 // Stepping on a shock vent shuts it down.
1493 if( ft == fd_shock_vent || ft == fd_acid_vent ) {
1494 cur.set_field_intensity( 0 );
1495 }
1496 if( ft == fd_bees ) {
1497 // Player is immune to bees while underwater.
1498 if( !u.is_underwater() ) {
1499 const int intensity = cur.get_field_intensity();
1500 // Bees will try to sting you in random body parts, up to 8 times.
1501 for( int i = 0; i < rng( 1, 7 ); i++ ) {
1503 int sum_cover = 0;
1504 for( const item &i : u.worn ) {
1505 if( i.covers( bp->token ) ) {
1506 sum_cover += i.get_coverage();
1507 }
1508 }
1509 // Get stung if [clothing on a body part isn't thick enough (like t-shirt) OR clothing covers less than 100% of body part]
1510 // AND clothing on affected body part has low environmental protection value
1511 if( ( u.get_armor_cut( bp ) <= 1 || ( sum_cover < 100 && x_in_y( 100 - sum_cover, 100 ) ) ) &&
1512 u.add_env_effect( effect_stung, bp->token, intensity, 9_minutes ) ) {
1513 u.add_msg_if_player( m_bad, _( "The bees sting you in %s!" ),
1514 body_part_name_accusative( bp->token ) );
1515 }
1516 }
1517 }
1518 }
1519 if( ft == fd_incendiary ) {
1520 // Mysterious incendiary substance melts you horribly.
1521 if( u.has_trait( trait_M_SKIN2 ) ||
1522 u.has_trait( trait_M_SKIN3 ) ||
1523 cur.get_field_intensity() == 1 ) {
1524 u.add_msg_player_or_npc( m_bad, _( "The incendiary burns you!" ),
1525 _( "The incendiary burns <npcname>!" ) );
1526 u.hurtall( rng( 1, 3 ), nullptr );
1527 } else {
1528 u.add_msg_player_or_npc( m_bad, _( "The incendiary melts into your skin!" ),
1529 _( "The incendiary melts into <npcname>s skin!" ) );
1530 u.add_effect( effect_onfire, 8_turns, bp_torso );
1531 u.hurtall( rng( 2, 6 ), nullptr );
1532 }
1533 }
1534 // Both gases are unhealthy and become deadly if you cross a related threshold.
1535 if( ft == fd_fungicidal_gas || ft == fd_insecticidal_gas ) {
1536 // The gas won't harm you inside a vehicle.
1537 if( !inside ) {
1538 // Full body suits protect you from the effects of the gas.
1539 if( !( u.worn_with_flag( flag_GAS_PROOF ) && u.get_env_resist( bodypart_id( "mouth" ) ) >= 15 &&
1540 u.get_env_resist( bodypart_id( "eyes" ) ) >= 15 ) ) {
1541 const int intensity = cur.get_field_intensity();
1542 bool inhaled = u.add_env_effect( effect_poison, bp_mouth, 5, intensity * 1_minutes );
1544 ( ft == fd_insecticidal_gas && ( u.get_highest_category() == "INSECT" ||
1545 u.get_highest_category() == "SPIDER" ) ) ) {
1546 inhaled |= u.add_env_effect( effect_badpoison, bp_mouth, 5, intensity * 1_minutes );
1547 u.hurtall( rng( intensity, intensity * 2 ), nullptr );
1548 u.add_msg_if_player( m_bad, _( "The %s burns your skin." ), cur.name() );
1549 }
1550
1551 if( inhaled ) {
1552 u.add_msg_if_player( m_bad, _( "The %s makes you feel sick." ), cur.name() );
1553 }
1554 }
1555 }
1556 }
1557 }
1558}
std::string body_part_name_accusative(body_part bp, int number)
Returns the matching accusative name of the body_part token, i.e.
Definition: bodypart.cpp:329
@ bp_foot_l
Definition: bodypart.h:50
@ bp_leg_r
Definition: bodypart.h:49
@ bp_eyes
Definition: bodypart.h:42
@ bp_hand_l
Definition: bodypart.h:46
@ bp_arm_l
Definition: bodypart.h:44
@ bp_leg_l
Definition: bodypart.h:48
@ bp_hand_r
Definition: bodypart.h:47
@ bp_head
Definition: bodypart.h:41
@ bp_torso
Definition: bodypart.h:40
@ bp_mouth
Definition: bodypart.h:43
@ bp_foot_r
Definition: bodypart.h:51
@ bp_arm_r
Definition: bodypart.h:45
bool is_elec_immune() const override
Returns true is the player is protected from electric shocks.
Definition: character.cpp:6202
bool worn_with_flag(const std::string &flag, const bodypart_id &bp=bodypart_str_id::NULL_ID()) const
Returns true if the player is wearing an item with the given flag.
Definition: character.cpp:3268
bool is_on_ground() const override
Returns true if the player is knocked over or has broken legs.
Definition: character.cpp:957
std::list< item > worn
Definition: character.h:1573
int get_env_resist(bodypart_id bp) const override
Returns overall env_resist on a body_part.
Definition: character.cpp:7143
bool has_two_arms() const
Returns true if the player has two functioning arms.
Definition: character.cpp:1275
int get_armor_cut(bodypart_id bp) const override
Returns overall cutting resistance for the body_part.
Definition: character.cpp:6986
std::string get_highest_category() const
Returns the highest mutation category.
Definition: character.cpp:7980
bool is_wearing(const item &itm) const
Returns true if the player is wearing the item.
Definition: character.cpp:3238
void hurtall(int dam, Creature *source, bool disturb=true)
Hurts all body parts for dam, no armor reduction.
Definition: character.cpp:8667
bool has_trait(const trait_id &b) const override
Returns true if the player has the entered trait.
Definition: mutation.cpp:103
bool irradiate(float rads, bool bypass=false)
Handles mitigation and application of radiation.
Definition: suffer.cpp:1532
static body_part hp_to_bp(hp_part hpart)
Converts an hp_part to a body_part.
Definition: character.cpp:6600
bool has_active_bionic(const bionic_id &b) const
Returns true if the player has the entered bionic id and it is powered on.
Definition: character.cpp:1885
bodypart_id get_random_body_part(bool main=false) const
Definition: creature.cpp:1617
virtual bool is_underwater() const
Definition: creature.cpp:174
std::vector< bodypart_id > get_all_body_parts(bool only_main=false) const
Returns body parts this creature have.
Definition: creature.cpp:1624
int extra_radiation_min() const
Definition: field.cpp:14
int radiation_hurt_damage_min() const
Definition: field.cpp:24
std::string radiation_hurt_message() const
Definition: field.cpp:34
int extra_radiation_max() const
Definition: field.cpp:19
std::string name() const
Definition: field.h:84
int radiation_hurt_damage_max() const
Definition: field.cpp:29
int get_coverage() const
Returns the relative coverage that this item has when worn.
Definition: item.cpp:5739
bool covers(body_part bp) const
Whether this item (when worn) covers the given body part.
Definition: item.cpp:739
int burn_body_part(player &u, field_entry &cur, body_part bp, int scale)
Definition: map_field.cpp:124
void mod_pain(int npain) override
Modifies a pain value by player traits before passing it to Creature::mod_pain()
Definition: player.cpp:1092
void add_msg_if_player(const std::string &msg) const override
Definition: player.cpp:4368
bool is_player() const override
Definition: player.h:114
field_type_id fd_bees
Definition: field_type.cpp:371
static const trait_id trait_M_SKIN3("M_SKIN3")
static const std::string flag_GAS_PROOF("GAS_PROOF")
static const efftype_id effect_fungus("fungus")
static const trait_id trait_ELECTRORECEPTORS("ELECTRORECEPTORS")
static const trait_id trait_THRESH_MARLOSS("THRESH_MARLOSS")
static const trait_id trait_WEB_WALKER("WEB_WALKER")
static const efftype_id effect_badpoison("badpoison")
static const itype_id itype_rm13_armor_on("rm13_armor_on")
static const trait_id trait_M_IMMUNE("M_IMMUNE")
static const trait_id trait_THRESH_MYCUS("THRESH_MYCUS")
static const trait_id trait_ACIDPROOF("ACIDPROOF")
static const trait_id trait_M_SKIN2("M_SKIN2")
static const efftype_id effect_stung("stung")
static const efftype_id effect_poison("poison")
static const efftype_id effect_teargas("teargas")
static const bionic_id bio_heatsink("bio_heatsink")
hp_part
Definition: pldata.h:32
@ num_hp_parts
Definition: pldata.h:39
int type_damage(damage_type dt) const
Definition: damage.cpp:172
#define translate_marker(x)
Marks a string literal to be extracted for translation.
Definition: translations.h:30

References _, Creature::add_effect(), Creature::add_env_effect(), add_msg(), player::add_msg_if_player(), player::add_msg_player_or_npc(), bio_heatsink, body_part_name_accusative(), bp_arm_l, bp_arm_r, bp_eyes, bp_foot_l, bp_foot_r, bp_hand_l, bp_hand_r, bp_head, bp_leg_l, bp_leg_r, bp_mouth, bp_torso, burn_body_part(), Creature::check_dead_state(), convert_bp(), item::covers(), Character::deal_damage(), DT_ELECTRIC, DT_HEAT, effect_badpoison, effect_blind, effect_fungus, effect_onfire, effect_poison, effect_stung, effect_teargas, effect_webbed, field_entry::extra_radiation_max(), field_entry::extra_radiation_min(), fd_acid, fd_acid_vent, fd_bees, fd_dazzling, fd_electricity, fd_fatigue, fd_fire, fd_flame_burst, fd_fungal_haze, fd_fungicidal_gas, fd_incendiary, fd_insecticidal_gas, fd_sap, fd_shock_vent, fd_sludge, fd_tear_gas, fd_web, flag_GAS_PROOF(), Creature::get_all_body_parts(), Character::get_armor_cut(), item::get_coverage(), Character::get_env_resist(), get_field(), field_entry::get_field_intensity(), field_entry::get_field_type(), Character::get_highest_category(), Creature::get_random_body_part(), Character::has_active_bionic(), Character::has_trait(), Character::has_two_arms(), Character::hp_to_bp(), Character::hurtall(), string_id< T >::id(), Character::in_vehicle, Character::irradiate(), Character::is_elec_immune(), field_entry::is_field_alive(), Character::is_on_ground(), player::is_player(), Creature::is_underwater(), Character::is_wearing(), itype_rm13_armor_on, m_bad, m_warning, player::mod_pain(), Creature::moves, field_entry::name(), num_bp, num_hp_parts, one_in(), Character::pos(), field_entry::radiation_hurt_damage_max(), field_entry::radiation_hurt_damage_min(), field_entry::radiation_hurt_message(), rng(), field_entry::set_field_intensity(), teleport::teleport(), dealt_damage_instance::total_damage(), trait_ACIDPROOF, trait_ELECTRORECEPTORS, trait_M_IMMUNE, trait_M_SKIN2, trait_M_SKIN3, trait_THRESH_MARLOSS, trait_THRESH_MYCUS, trait_WEB_WALKER, translate_marker, dealt_damage_instance::type_damage(), veh_at(), Character::worn, Character::worn_with_flag(), and x_in_y().

Referenced by creature_in_field().

◆ point_within_camp()

bool map::point_within_camp ( const tripoint point_check) const

Definition at line 5531 of file map.cpp.

5532{
5533 // TODO: fix point types
5534 const tripoint_abs_omt omt_check( ms_to_omt_copy( point_check ) );
5535 const point_abs_omt p = omt_check.xy();
5536 for( int x2 = -2; x2 < 2; x2++ ) {
5537 for( int y2 = -2; y2 < 2; y2++ ) {
5538 if( cata::optional<basecamp *> bcp = overmap_buffer.find_camp( p + point( x2, y2 ) ) ) {
5539 return ( *bcp )->camp_omt_pos().z() == point_check.z;
5540 }
5541 }
5542 }
5543 return false;
5544}
constexpr auto xy() const
Definition: coordinates.h:130
cata::optional< basecamp * > find_camp(const point_abs_omt &p)

References overmapbuffer::find_camp(), ms_to_omt_copy(), overmap_buffer, coords::coord_point< Point, Origin, Scale >::xy(), and tripoint::z.

Referenced by npc::worker_downtime().

◆ points_in_radius()

tripoint_range< tripoint > map::points_in_radius ( const tripoint center,
size_t  radius,
size_t  radiusz = 0 
) const

Definition at line 8422 of file map.cpp.

8424{
8425 const tripoint min( std::max<int>( 0, center.x - radius ), std::max<int>( 0, center.y - radius ),
8426 clamp<int>( center.z - radiusz, -OVERMAP_DEPTH, OVERMAP_HEIGHT ) );
8427 const tripoint max( std::min<int>( SEEX * my_MAPSIZE - 1, center.x + radius ),
8428 std::min<int>( SEEX * my_MAPSIZE - 1, center.y + radius ), clamp<int>( center.z + radiusz,
8430 return tripoint_range<tripoint>( min, max );
8431}

References center, my_MAPSIZE, OVERMAP_DEPTH, OVERMAP_HEIGHT, and SEEX.

Referenced by computer_session::action_blood_anal(), computer_session::action_conveyor(), computer_session::action_data_anal(), computer_session::action_deactivate_shock_vent(), computer_session::action_extract_rad_source(), computer_session::action_geiger(), computer_session::action_irradiator(), computer_session::action_sample(), Character::activate_bionic(), add_splash(), Character::adjacent_tile(), npc::alt_attack(), are_requirements_nearby(), npc::assess_danger(), bash_furn_success(), Character::blossoms(), build_vision_transparency_cache(), activity_handlers::butcher_finish(), leap_actor::call(), can_do_activity_there(), iexamine::cardreader(), iexamine::cardreader_foodplace(), deploy_tent_actor::check_intact(), choose_adjacent_highlight(), activity_handlers::chop_tree_finish(), climb_difficulty(), collapse_at(), collapse_check(), complete_construction(), consider_butchery(), game::control_vehicle(), displace_water(), enumerate_objects_around_point(), Character::env_surgery_bonus(), ranged::execute_shaped_attack(), ranged::expected_coverage(), computer_session::failure_destroy_blood(), computer_session::failure_destroy_data(), computer_session::failure_manhacks(), computer_session::failure_secubots(), computer_session::failure_shutdown(), find_empty_spot_nearby(), find_furnitures_with_flag_in_radius(), find_potential_computer_point(), hacking_activity_actor::finish(), activity_handlers::forage_finish(), game::forced_door_closing(), basecamp::form_crafting_inventory(), inventory::form_from_map(), generic_multi_activity_check_requirement(), generic_multi_activity_locations(), get_creatures_in_radius(), get_heat_radiation(), liquid_handler::get_liquid_target(), zone_manager::get_point_set_loot(), iexamine::getGasPumpByNumber(), iexamine::getNearFilledGasTank(), getNearPumpCount(), npc::go_to_omt_destination(), handle_action_menu(), has_adjacent_furniture_with(), has_nearby_chair(), has_nearby_fire(), has_nearby_table(), has_neighbor(), is_cornerfloor(), is_wall_adjacent(), game::monmove(), npc::move_away_from(), MapExtras::mx_casings(), MapExtras::mx_corpses(), MapExtras::mx_looters(), MapExtras::mx_marloss_pilgrimage(), MapExtras::mx_mayhem(), MapExtras::mx_minefield(), MapExtras::mx_portal(), MapExtras::mx_portal_in(), iexamine::nanofab(), iuse::note_bionics(), trap::on_disarmed(), operator_present(), tutorial_game::per_turn(), photo_def_for_camera_point(), place_construction(), game::place_critter_around(), mission_start::place_deposit_box(), game::place_player(), place_vending(), player_on_couch(), iexamine::portable_structure(), tutorial_game::post_action(), game::process_artifact(), process_fields_in_submap(), propagate_suspension_check(), avatar_action::ramp_move(), reachable_flood_steps(), editmap::recalc_target(), requirements_map(), route_adjacent(), mattack::shriek_stun(), spawn_monsters_submap(), mdeath::splatter(), Character::spores(), fungal_effects::spread_fungus(), spread_gas(), monster::stumble(), activity_handlers::travel_do_turn(), explosion_iuse::trigger_explosion(), try_remove_grab(), turnOnSelectedPump(), place_trap_actor::use(), deploy_tent_actor::use(), use_amount(), game::vertical_move(), and npc::worker_downtime().

◆ points_in_rectangle()

tripoint_range< tripoint > map::points_in_rectangle ( const tripoint from,
const tripoint to 
) const

Definition at line 8412 of file map.cpp.

8413{
8414 const tripoint min( std::max( 0, std::min( from.x, to.x ) ), std::max( 0, std::min( from.y,
8415 to.y ) ), std::max( -OVERMAP_DEPTH, std::min( from.z, to.z ) ) );
8416 const tripoint max( std::min( SEEX * my_MAPSIZE - 1, std::max( from.x, to.x ) ),
8417 std::min( SEEX * my_MAPSIZE - 1, std::max( from.y, to.y ) ), std::min( OVERMAP_HEIGHT,
8418 std::max( from.z, to.z ) ) );
8419 return tripoint_range<tripoint>( min, max );
8420}

References my_MAPSIZE, OVERMAP_DEPTH, OVERMAP_HEIGHT, SEEX, tripoint::x, tripoint::y, and tripoint::z.

Referenced by apply_camp_ownership(), apply_faction_ownership(), debug_menu::debug(), draw_lab(), farm_action(), game::find_or_make_stairs(), generate_lightmap(), jmapgen_setmap::has_vehicle_collision(), avatar_action::move(), MapExtras::mx_portal(), om_cutdown_trees(), om_harvest_furn(), om_harvest_itm(), and om_harvest_ter().

◆ points_on_zlevel() [1/2]

◆ points_on_zlevel() [2/2]

tripoint_range< tripoint > map::points_on_zlevel ( int  z) const

Same as above, but uses the specific z-level.

If the given z-level is invalid, it returns an empty range.

Definition at line 8433 of file map.cpp.

8434{
8435 if( z < -OVERMAP_DEPTH || z > OVERMAP_HEIGHT ) {
8436 // TODO: need a default constructor that creates an empty range.
8438 }
8440 tripoint( 0, 0, z ), tripoint( SEEX * my_MAPSIZE - 1, SEEY * my_MAPSIZE - 1, z ) );
8441}

References my_MAPSIZE, OVERMAP_HEIGHT, SEEX, SEEY, tripoint_above, and tripoint_zero.

◆ process_falling()

void map::process_falling ( )

Invoked drop_everything on cached dirty tiles.

Definition at line 2269 of file map.cpp.

2270{
2271 if( !zlevels ) {
2272 support_cache_dirty.clear();
2273 return;
2274 }
2275
2276 if( !support_cache_dirty.empty() ) {
2277 add_msg( m_debug, "Checking %d tiles for falling objects",
2278 support_cache_dirty.size() );
2279 // We want the cache to stay constant, but falling can change it
2280 std::set<tripoint> last_cache = std::move( support_cache_dirty );
2281 support_cache_dirty.clear();
2282 for( const tripoint &p : last_cache ) {
2283 drop_everything( p );
2284 }
2285 }
2286}
void drop_everything(const tripoint &p)
Handles map objects of given type (not creatures) falling down.
Definition: map.cpp:2040
std::set< tripoint > support_cache_dirty
Definition: map.h:1523

References add_msg(), drop_everything(), m_debug, avatar_action::move(), support_cache_dirty, and zlevels.

Referenced by game::do_turn().

◆ process_fields()

void map::process_fields ( )

Definition at line 141 of file map_field.cpp.

142{
143 const int minz = zlevels ? -OVERMAP_DEPTH : abs_sub.z;
144 const int maxz = zlevels ? OVERMAP_HEIGHT : abs_sub.z;
145 for( int z = minz; z <= maxz; z++ ) {
146 auto &field_cache = get_cache( z ).field_cache;
147 for( int x = 0; x < my_MAPSIZE; x++ ) {
148 for( int y = 0; y < my_MAPSIZE; y++ ) {
149 if( field_cache[ x + y * MAPSIZE ] ) {
150 submap *const current_submap = get_submap_at_grid( { x, y, z } );
151 process_fields_in_submap( current_submap, tripoint( x, y, z ) );
152 }
153 }
154 }
155
156 // no need to invalidate "transparency" and "seen" caches here
157 // they are invalidated point by point inside the `process_fields_in_submap`
158 }
159}
void process_fields_in_submap(submap *current_submap, const tripoint &submap_pos)
Definition: map_field.cpp:394

References abs_sub, level_cache::field_cache, get_cache(), get_submap_at_grid(), MAPSIZE, my_MAPSIZE, OVERMAP_DEPTH, OVERMAP_HEIGHT, process_fields_in_submap(), tripoint::z, and zlevels.

Referenced by game::do_turn().

◆ process_fields_in_submap()

void map::process_fields_in_submap ( submap current_submap,
const tripoint submap_pos 
)

Definition at line 394 of file map_field.cpp.

396{
397 scent_block sblk( submap, g->scent );
398
399 // Holds m.field_at(x,y).find_field(fd_some_field) type returns.
400 // Just to avoid typing that long string for a temp value.
401 field_entry *tmpfld = nullptr;
402
403 map &here = get_map();
404 tripoint thep;
405 thep.z = submap.z;
406
407 // Initialize the map tile wrapper
408 maptile map_tile( current_submap, point_zero );
409 int &locx = map_tile.pos_.x;
410 int &locy = map_tile.pos_.y;
411 const point sm_offset( submap.x * SEEX, submap.y * SEEY );
412
413 // Loop through all tiles in this submap indicated by current_submap
414 for( locx = 0; locx < SEEX; locx++ ) {
415 for( locy = 0; locy < SEEY; locy++ ) {
416 // Get a reference to the field variable from the submap;
417 // contains all the pointers to the real field effects.
418 field &curfield = current_submap->get_field( { static_cast<int>( locx ), static_cast<int>( locy ) } );
419
420 // when displayed_field_type == fd_null it means that `curfield` has no fields inside
421 // avoids instantiating (relatively) expensive map iterator
422 if( !curfield.displayed_field_type() ) {
423 continue;
424 }
425
426 // This is a translation from local coordinates to submap coordinates.
427 // All submaps are in one long 1d array.
428 thep.x = locx + sm_offset.x;
429 thep.y = locy + sm_offset.y;
430 // A const reference to the tripoint above, so that the code below doesn't accidentally change it
431 const tripoint &p = thep;
432
433 // This should be true only when the field in the current tile changes transparency state,
434 // More correctly: not just when the field is opaque, but when it changes state
435 // to a more/less transparent one
436 bool dirty_transparency_cache = false;
437
438 for( auto it = curfield.begin(); it != curfield.end(); ) {
439 // Iterating through all field effects in the submap's field.
440 field_entry &cur = it->second;
441
442 // Holds cur.get_field_type() as that is what the old system used before rewrite.
443 field_type_id cur_fd_type_id = cur.get_field_type();
444
445 // The field might have been killed by processing a neighbor field
446 if( !cur.is_field_alive() ) {
447 if( !cur_fd_type_id->get_transparent( cur.get_field_intensity() - 1 ) ) {
448 dirty_transparency_cache = true;
449 }
450 --current_submap->field_count;
451 curfield.remove_field( it++ );
452 continue;
453 }
454
455 // Again, legacy support in the event someone Mods set_field_intensity to allow more values.
456 if( cur.get_field_intensity() > 3 || cur.get_field_intensity() < 1 ) {
457 // TODO: Remove this eventually as we would suppoort more than 3 field intensity levels
458 debugmsg( "Whoooooa intensity of %d", cur.get_field_intensity() );
459 }
460
461 dirty_transparency_cache |= cur_fd_type_id->dirty_transparency_cache;
462
463 // Don't process "newborn" fields. This gives the player time to run if they need to.
464 if( cur.get_field_age() == 0_turns ) {
465 cur_fd_type_id = fd_null;
466 }
467
468 const field_type &cur_fd_type = *cur_fd_type_id;
469
470 // Upgrade field intensity
471 if( cur.intensity_upgrade_chance() > 0 &&
473 cur.intensity_upgrade_duration() > 0_turns &&
476 }
477
478 int part;
479 const ter_t &ter = map_tile.get_ter_t();
480 // Dissipate faster in water
481 if( ter.has_flag( TFLAG_SWIMMABLE ) ) {
483 }
484 if( cur_fd_type_id == fd_acid ) {
485 // Try to fall by a z-level
486 if( zlevels && p.z > -OVERMAP_DEPTH ) {
487 tripoint dst{ p.xy(), p.z - 1 };
488 if( valid_move( p, dst, true, true ) ) {
489 field_entry *acid_there = field_at( dst ).find_field( fd_acid );
490 if( acid_there == nullptr ) {
492 } else {
493 // Math can be a bit off,
494 // but "boiling" falling acid can be allowed to be stronger
495 // than acid that just lies there
496 const int sum_intensity = cur.get_field_intensity() + acid_there->get_field_intensity();
497 const int new_intensity = std::min( 3, sum_intensity );
498 // No way to get precise elapsed time, let's always reset
499 // Allow falling acid to last longer than regular acid to show it off
500 const time_duration new_age = -1_minutes * ( sum_intensity - new_intensity );
501 acid_there->set_field_intensity( new_intensity );
502 acid_there->set_field_age( new_age );
503 }
504
505 // Set ourselves up for removal
506 cur.set_field_intensity( 0 );
507 }
508 }
509 // TODO: Allow spreading to the sides if age < 0 && intensity == 3
510 }
511 if( cur_fd_type.apply_slime_factor > 0 ) {
512 sblk.apply_slime( p, cur.get_field_intensity() * cur_fd_type.apply_slime_factor );
513 }
514 if( cur_fd_type_id == fd_fire ) {
515 cur.set_field_age( std::max( -24_hours, cur.get_field_age() ) );
516 // Entire objects for ter/frn for flags
517 const ter_t &ter = map_tile.get_ter_t();
518 const furn_t &frn = map_tile.get_furn_t();
519
520 // We've got ter/furn cached, so let's use that
521 const bool is_sealed = ter_furn_has_flag( ter, frn, TFLAG_SEALED ) &&
523 // Consumed items count
524 int consumed = 0;
525 // How much time to add to the fire's life due to burned items/terrain/furniture
526 time_duration time_added = 0_turns;
527 // Checks if the fire can spread
528 const bool can_spread = !ter_furn_has_flag( ter, frn, TFLAG_FIRE_CONTAINER );
529 const bool no_floor = ter.has_flag( TFLAG_NO_FLOOR );
530 // If the flames are in furniture with fire_container flag like brazier or oven,
531 // they're fully contained, so skip consuming terrain
532 const bool can_burn = !no_floor && can_spread &&
533 ( check_flammable( ter ) || check_flammable( frn ) );
534 // The huge indent below should probably be somehow moved away from here
535 // without forcing the function to use i_at( p ) for fires without items
536 if( !is_sealed && map_tile.get_item_count() > 0 ) {
537 map_stack items_here = i_at( p );
538 std::vector<item> new_content;
539 for( auto explosive = items_here.begin(); explosive != items_here.end(); ) {
540 if( explosive->will_explode_in_fire() ) {
541 // We need to make a copy because the iterator validity is not predictable
542 item copy = *explosive;
543 explosive = items_here.erase( explosive );
544 if( copy.detonate( p, new_content ) ) {
545 // Need to restart, iterators may not be valid
546 explosive = items_here.begin();
547 }
548 } else {
549 ++explosive;
550 }
551 }
552
553 fire_data frd( cur.get_field_intensity(), !can_spread );
554 // The highest # of items this fire can remove in one turn
555 int max_consume = cur.get_field_intensity() * 2;
556
557 for( auto fuel = items_here.begin(); fuel != items_here.end() && consumed < max_consume; ) {
558 // `item::burn` modifies the charges in order to simulate some of them getting
559 // destroyed by the fire, this changes the item weight, but may not actually
560 // destroy it. We need to spawn products anyway.
561 const units::mass old_weight = fuel->weight( false );
562 bool destroyed = fuel->burn( frd );
563 // If the item is considered destroyed, it may have negative charge count,
564 // see `item::burn?. This in turn means `item::weight` returns a negative value,
565 // which we can not use, so only call `weight` when it's still an existing item.
566 const units::mass new_weight = destroyed ? 0_gram : fuel->weight( false );
567 if( old_weight != new_weight ) {
568 create_burnproducts( p, *fuel, old_weight - new_weight );
569 }
570
571 if( destroyed ) {
572 // If we decided the item was destroyed by fire, remove it.
573 // But remember its contents, except for irremovable mods, if any
574 const std::list<item *> content_list = fuel->contents.all_items_top();
575 for( item *it : content_list ) {
576 if( !it->is_irremovable() ) {
577 new_content.push_back( item( *it ) );
578 }
579 }
580 fuel = items_here.erase( fuel );
581 consumed++;
582 } else {
583 ++fuel;
584 }
585 }
586
587 spawn_items( p, new_content );
588 time_added = 1_turns * roll_remainder( frd.fuel_produced );
589 }
590
591 // Get the part of the vehicle in the fire (_internal skips the boundary check)
592 vehicle *veh = veh_at_internal( p, part );
593 if( veh != nullptr ) {
594 veh->damage( part, cur.get_field_intensity() * 10, DT_HEAT, true );
595 // Damage the vehicle in the fire.
596 }
597 if( can_burn ) {
598 if( ter.has_flag( TFLAG_SWIMMABLE ) ) {
599 // Flames die quickly on water
600 cur.set_field_age( cur.get_field_age() + 4_minutes );
601 }
602
603 // Consume the terrain we're on
604 if( ter_furn_has_flag( ter, frn, TFLAG_FLAMMABLE ) ) {
605 // The fire feeds on the ground itself until max intensity.
606 time_added += 1_turns * ( 5 - cur.get_field_intensity() );
607 if( cur.get_field_intensity() > 1 &&
608 one_in( 200 - cur.get_field_intensity() * 50 ) ) {
609 destroy( p, false );
610 }
611
612 } else if( ter_furn_has_flag( ter, frn, TFLAG_FLAMMABLE_HARD ) &&
613 one_in( 3 ) ) {
614 // The fire feeds on the ground itself until max intensity.
615 time_added += 1_turns * ( 4 - cur.get_field_intensity() );
616 if( cur.get_field_intensity() > 1 &&
617 one_in( 200 - cur.get_field_intensity() * 50 ) ) {
618 destroy( p, false );
619 }
620
621 } else if( ter.has_flag( TFLAG_FLAMMABLE_ASH ) ) {
622 // The fire feeds on the ground itself until max intensity.
623 time_added += 1_turns * ( 5 - cur.get_field_intensity() );
624 if( cur.get_field_intensity() > 1 &&
625 one_in( 200 - cur.get_field_intensity() * 50 ) ) {
626 if( p.z > 0 ) {
627 // We're in the air
628 ter_set( p, t_open_air );
629 } else {
630 ter_set( p, t_dirt );
631 }
632 }
633
634 } else if( frn.has_flag( TFLAG_FLAMMABLE_ASH ) ) {
635 // The fire feeds on the ground itself until max intensity.
636 time_added += 1_turns * ( 5 - cur.get_field_intensity() );
637 if( cur.get_field_intensity() > 1 &&
638 one_in( 200 - cur.get_field_intensity() * 50 ) ) {
639 furn_set( p, f_ash );
640 add_item_or_charges( p, item( "ash" ) );
641 }
642
643 }
644 }
645
646 if( ter.has_flag( TFLAG_NO_FLOOR ) && zlevels && p.z > -OVERMAP_DEPTH ) {
647 // We're hanging in the air - let's fall down
648 tripoint dst{ p.xy(), p.z - 1 };
649 if( valid_move( p, dst, true, true ) ) {
650 maptile dst_tile = maptile_at_internal( dst );
651 field_entry *fire_there = dst_tile.find_field( fd_fire );
652 if( fire_there == nullptr ) {
653 add_field( dst, fd_fire, 1, 0_turns, false );
655 } else {
656 // Don't fuel raging fires or they'll burn forever
657 // as they can produce small fires above themselves
658 int new_intensity = std::max( cur.get_field_intensity(),
659 fire_there->get_field_intensity() );
660 // Allow smaller fires to combine
661 if( new_intensity < 3 &&
662 cur.get_field_intensity() == fire_there->get_field_intensity() ) {
663 new_intensity++;
664 }
665 // A raging fire below us can support us for a while
666 // Otherwise decay and decay fast
667 if( fire_there->get_field_intensity() < 3 || one_in( 10 ) ) {
669 }
670 fire_there->set_field_intensity( new_intensity );
671 }
672 break;
673 }
674 }
675 // Lower age is a longer lasting fire
676 if( time_added != 0_turns ) {
677 cur.set_field_age( cur.get_field_age() - time_added );
678 } else if( can_burn ) {
679 // Nothing to burn = fire should be dying out faster
680 // Drain more power from big fires, so that they stop raging over nothing
681 // Except for fires on stoves and fireplaces, those are made to keep the fire alive
682 cur.mod_field_age( 10_seconds * cur.get_field_intensity() );
683 }
684
685 // Allow raging fires (and only raging fires) to spread up
686 // Spreading down is achieved by wrecking the walls/floor and then falling
687 if( zlevels && cur.get_field_intensity() == 3 && p.z < OVERMAP_HEIGHT ) {
688 const tripoint dst_p = tripoint( p.xy(), p.z + 1 );
689 // Let it burn through the floor
690 maptile dst = maptile_at_internal( dst_p );
691 const auto &dst_ter = dst.get_ter_t();
692 if( dst_ter.has_flag( TFLAG_NO_FLOOR ) ||
693 dst_ter.has_flag( TFLAG_FLAMMABLE ) ||
694 dst_ter.has_flag( TFLAG_FLAMMABLE_ASH ) ||
695 dst_ter.has_flag( TFLAG_FLAMMABLE_HARD ) ) {
696 field_entry *nearfire = dst.find_field( fd_fire );
697 if( nearfire != nullptr ) {
698 nearfire->mod_field_age( -2_turns );
699 } else {
700 add_field( dst_p, fd_fire, 1, 0_turns, false );
701 }
702 // Fueling fires above doesn't cost fuel
703 }
704 }
705
706 // Below we will access our nearest 8 neighbors, so let's cache them now
707 // This should probably be done more globally, because large fires will re-do it a lot
708 auto neighs = get_neighbors( p );
709
710 // If the flames are in a pit, it can't spread to non-pit
711 const bool in_pit = can_spread && ter.id.id() == t_pit;
712
713 // Count adjacent fires, to optimize out needless smoke and hot air
714 int adjacent_fires = 0;
715
716 // If the flames are big, they contribute to adjacent flames
717 if( can_spread ) {
718 if( cur.get_field_intensity() > 1 && one_in( 3 ) ) {
719 // Basically: Scan around for a spot,
720 // if there is more fire there, make it bigger and give it some fuel.
721 // This is how big fires spend their excess age:
722 // making other fires bigger. Flashpoint.
723 size_t end_it = static_cast<size_t>( rng( 0, neighs.size() - 1 ) );
724 for( size_t i = ( end_it + 1 ) % neighs.size(), count = 0;
725 count != neighs.size() && cur.get_field_age() < 0_turns;
726 i = ( i + 1 ) % neighs.size(), count++ ) {
727 maptile &dst = neighs[i].second;
728 auto dstfld = dst.find_field( fd_fire );
729 // If the fire exists and is weaker than ours, boost it
730 if( dstfld != nullptr &&
731 ( dstfld->get_field_intensity() <= cur.get_field_intensity() ||
732 dstfld->get_field_age() > cur.get_field_age() ) &&
733 ( in_pit == ( dst.get_ter() == t_pit ) ) ) {
734 if( dstfld->get_field_intensity() < 2 ) {
735 dstfld->set_field_intensity( dstfld->get_field_intensity() + 1 );
736 }
737
738 dstfld->set_field_age( dstfld->get_field_age() - 5_minutes );
739 cur.set_field_age( cur.get_field_age() + 5_minutes );
740 }
741 if( dstfld != nullptr ) {
742 adjacent_fires++;
743 }
744 }
745 } else if( cur.get_field_age() < 0_turns && cur.get_field_intensity() < 3 ) {
746 // See if we can grow into a stage 2/3 fire, for this
747 // burning neighbors are necessary in addition to
748 // field age < 0, or alternatively, a LOT of fuel.
749
750 // The maximum fire intensity is 1 for a lone fire, 2 for at least 1 neighbor,
751 // 3 for at least 2 neighbors.
752 int maximum_intensity = 1;
753
754 // The following logic looks a bit complex due to optimization concerns, so here are the semantics:
755 // 1. Calculate maximum field intensity based on fuel, -50 minutes is 2(medium), -500 minutes is 3(raging)
756 // 2. Calculate maximum field intensity based on neighbors, 3 neighbors is 2(medium), 7 or more neighbors is 3(raging)
757 // 3. Pick the higher maximum between 1. and 2.
758 if( cur.get_field_age() < -500_minutes ) {
759 maximum_intensity = 3;
760 } else {
761 for( auto &neigh : neighs ) {
762 if( neigh.second.get_field().find_field( fd_fire ) != nullptr ) {
763 adjacent_fires++;
764 }
765 }
766 maximum_intensity = 1 + ( adjacent_fires >= 3 ) + ( adjacent_fires >= 7 );
767
768 if( maximum_intensity < 2 && cur.get_field_age() < -50_minutes ) {
769 maximum_intensity = 2;
770 }
771 }
772
773 // If we consumed a lot, the flames grow higher
774 if( cur.get_field_intensity() < maximum_intensity && cur.get_field_age() < 0_turns ) {
775 // Fires under 0 age grow in size. Level 3 fires under 0 spread later on.
776 // Weaken the newly-grown fire
778 cur.set_field_age( cur.get_field_age() + 10_minutes * cur.get_field_intensity() );
779 }
780 }
781
782 // Consume adjacent fuel / terrain / webs to spread.
783 // Our iterator will start at end_i + 1 and increment from there and then wrap around.
784 // This guarantees it will check all neighbors, starting from a random one
785 const size_t end_i = static_cast<size_t>( rng( 0, neighs.size() - 1 ) );
786 for( size_t i = ( end_i + 1 ) % neighs.size(), count = 0;
787 count != neighs.size();
788 i = ( i + 1 ) % neighs.size(), count++ ) {
789 if( one_in( cur.get_field_intensity() * 2 ) ) {
790 // Skip some processing to save on CPU
791 continue;
792 }
793
794 tripoint &dst_p = neighs[i].first;
795 maptile &dst = neighs[i].second;
796 // No bounds checking here: we'll treat the invalid neighbors as valid.
797 // We're using the map tile wrapper, so we can treat invalid tiles as sentinels.
798 // This will create small oddities on map edges, but nothing more noticeable than
799 // "cut-off" that happens with bounds checks.
800
801 field_entry *nearfire = dst.find_field( fd_fire );
802 if( nearfire != nullptr ) {
803 // We handled supporting fires in the section above, no need to do it here
804 continue;
805 }
806
807 field_entry *nearwebfld = dst.find_field( fd_web );
808 int spread_chance = 25 * ( cur.get_field_intensity() - 1 );
809 if( nearwebfld != nullptr ) {
810 spread_chance = 50 + spread_chance / 2;
811 }
812
813 const ter_t &dster = dst.get_ter_t();
814 const furn_t &dsfrn = dst.get_furn_t();
815 // Allow weaker fires to spread occasionally
816 const int power = cur.get_field_intensity() + one_in( 5 );
817 if( can_spread && rng( 1, 100 ) < spread_chance &&
818 ( check_flammable( dster ) || check_flammable( dsfrn ) ) &&
819 ( in_pit == ( dster.id.id() == t_pit ) ) &&
820 (
821 ( power >= 3 && cur.get_field_age() < 0_turns && one_in( 20 ) ) ||
822 ( power >= 2 && ( ter_furn_has_flag( dster, dsfrn, TFLAG_FLAMMABLE ) && one_in( 2 ) ) ) ||
823 ( power >= 2 && ( ter_furn_has_flag( dster, dsfrn, TFLAG_FLAMMABLE_ASH ) && one_in( 2 ) ) ) ||
824 ( power >= 3 && ( ter_furn_has_flag( dster, dsfrn, TFLAG_FLAMMABLE_HARD ) && one_in( 5 ) ) ) ||
825 nearwebfld || ( dst.get_item_count() > 0 &&
827 one_in( 5 ) )
828 ) ) {
829 // Nearby open flammable ground? Set it on fire.
830 add_field( dst_p, fd_fire, 1, 0_turns, false );
831 tmpfld = dst.find_field( fd_fire );
832 if( tmpfld != nullptr ) {
833 // Make the new fire quite weak, so that it doesn't start jumping around instantly
834 tmpfld->set_field_age( 2_minutes );
835 // Consume a bit of our fuel
836 cur.set_field_age( cur.get_field_age() + 1_minutes );
837 }
838 if( nearwebfld ) {
839 nearwebfld->set_field_intensity( 0 );
840 }
841 }
842 }
843 }
844 }
845
846 // Spread gaseous fields
847 if( cur.gas_can_spread() ) {
848 const int gas_percent_spread = cur_fd_type.percent_spread;
849 if( gas_percent_spread > 0 ) {
850 const time_duration outdoor_age_speedup = cur_fd_type.outdoor_age_speedup;
851 spread_gas( cur, p, gas_percent_spread, outdoor_age_speedup, sblk );
852 }
853 }
854
855 if( cur_fd_type_id == fd_fungal_haze ) {
856 if( one_in( 10 - 2 * cur.get_field_intensity() ) ) {
857 // Haze'd terrain
858 fungal_effects( *g, here ).spread_fungus( p );
859 }
860 }
861
862 // Process npc complaints
863 const std::tuple<int, std::string, time_duration, std::string> &npc_complain_data =
864 cur_fd_type.npc_complain_data;
865 const int chance = std::get<0>( npc_complain_data );
866 if( chance > 0 && one_in( chance ) ) {
867 if( npc *const np = g->critter_at<npc>( p, false ) ) {
868 np->complain_about( std::get<1>( npc_complain_data ),
869 std::get<2>( npc_complain_data ),
870 std::get<3>( npc_complain_data ) );
871 }
872 }
873
874 // Apply radiation
875 if( cur.extra_radiation_max() > 0 ) {
876 int extra_radiation = rng( cur.extra_radiation_min(), cur.extra_radiation_max() );
877 adjust_radiation( p, extra_radiation );
878 }
879
880 // Apply wandering fields from vents
881 if( cur_fd_type.wandering_field ) {
882 for( const tripoint &pnt : points_in_radius( p, cur.get_field_intensity() - 1 ) ) {
883 field &wandering_field = get_field( pnt );
884 tmpfld = wandering_field.find_field( cur_fd_type.wandering_field );
885 if( tmpfld && tmpfld->get_field_intensity() < cur.get_field_intensity() ) {
886 tmpfld->set_field_intensity( tmpfld->get_field_intensity() + 1 );
887 } else {
888 add_field( pnt, cur_fd_type.wandering_field, cur.get_field_intensity() );
889 }
890 }
891 }
892
893 if( cur_fd_type_id == fd_fire_vent ) {
894
895 if( cur.get_field_intensity() > 1 ) {
896 if( one_in( 3 ) ) {
898 }
900 } else {
901 dirty_transparency_cache = true;
902 add_field( p, fd_flame_burst, 3, cur.get_field_age() );
903 cur.set_field_intensity( 0 );
904 }
905 }
906 if( cur_fd_type_id == fd_flame_burst ) {
907 if( cur.get_field_intensity() > 1 ) {
910 } else {
911 dirty_transparency_cache = true;
912 add_field( p, fd_fire_vent, 3, cur.get_field_age() );
913 cur.set_field_intensity( 0 );
914 }
915 }
916 if( cur_fd_type_id == fd_electricity ) {
917 // 4 in 5 chance to spread
918 if( !one_in( 5 ) ) {
919 std::vector<tripoint> valid;
920 // We're grounded
921 if( impassable( p ) && cur.get_field_intensity() > 1 ) {
922 int tries = 0;
923 tripoint pnt;
924 pnt.z = p.z;
925 while( tries < 10 && cur.get_field_age() < 5_minutes && cur.get_field_intensity() > 1 ) {
926 pnt.x = p.x + rng( -1, 1 );
927 pnt.y = p.y + rng( -1, 1 );
928 if( passable( pnt ) ) {
929 add_field( pnt, fd_electricity, 1, cur.get_field_age() + 1_turns );
931 tries = 0;
932 } else {
933 tries++;
934 }
935 }
936 // We're not grounded; attempt to ground
937 } else {
938 for( const tripoint &dst : points_in_radius( p, 1 ) ) {
939 // Grounded tiles first
940 if( impassable( dst ) ) {
941 valid.push_back( dst );
942 }
943 }
944 // Spread to adjacent space, then
945 if( valid.empty() ) {
946 tripoint dst( p + point( rng( -1, 1 ), rng( -1, 1 ) ) );
947 field_entry *elec = get_field( dst ).find_field( fd_electricity );
948 if( passable( dst ) && elec != nullptr &&
949 elec->get_field_intensity() < 3 ) {
950 elec->set_field_intensity( elec->get_field_intensity() + 1 );
952 } else if( passable( dst ) ) {
953 add_field( dst, fd_electricity, 1, cur.get_field_age() + 1_turns );
954 }
956 }
957 while( !valid.empty() && cur.get_field_intensity() > 1 ) {
958 const tripoint target = random_entry_removed( valid );
959 add_field( target, fd_electricity, 1, cur.get_field_age() + 1_turns );
961 }
962 }
963 }
964 }
965
966 int monster_spawn_chance = cur.monster_spawn_chance();
967 int monster_spawn_count = cur.monster_spawn_count();
968 if( monster_spawn_count > 0 && monster_spawn_chance > 0 && one_in( monster_spawn_chance ) ) {
969 for( ; monster_spawn_count > 0; monster_spawn_count-- ) {
971 cur.monster_spawn_group(), &monster_spawn_count );
972 if( !spawn_details.name ) {
973 continue;
974 }
977 [this]( const tripoint & n ) {
978 return passable( n );
979 } ) ) {
980 add_spawn( spawn_details.name, spawn_details.pack_size, *spawn_point );
981 }
982 }
983 }
984
985 if( cur_fd_type_id == fd_push_items ) {
986 map_stack items = i_at( p );
987 for( auto pushee = items.begin(); pushee != items.end(); ) {
988 if( pushee->typeId() != itype_rock ||
989 pushee->age() < 1_turns ) {
990 pushee++;
991 } else {
992 item tmp = *pushee;
993 tmp.set_age( 0_turns );
994 pushee = items.erase( pushee );
995 std::vector<tripoint> valid;
996 for( const tripoint &dst : points_in_radius( p, 1 ) ) {
997 if( get_field( dst, fd_push_items ) != nullptr ) {
998 valid.push_back( dst );
999 }
1000 }
1001 if( !valid.empty() ) {
1002 tripoint newp = random_entry( valid );
1003 add_item_or_charges( newp, tmp );
1004 if( g->u.pos() == newp ) {
1005 add_msg( m_bad, _( "A %s hits you!" ), tmp.tname() );
1006 const bodypart_id hit = g->u.get_random_body_part();
1007 g->u.deal_damage( nullptr, hit, damage_instance( DT_BASH, 6 ) );
1008 g->u.check_dead_state();
1009 }
1010
1011 if( npc *const p = g->critter_at<npc>( newp ) ) {
1012 // TODO: combine with player character code above
1013 const bodypart_id hit = g->u.get_random_body_part();
1014 p->deal_damage( nullptr, hit, damage_instance( DT_BASH, 6 ) );
1015 if( g->u.sees( newp ) ) {
1016 add_msg( _( "A %1$s hits %2$s!" ), tmp.tname(), p->name );
1017 }
1018 p->check_dead_state();
1019 } else if( monster *const mon = g->critter_at<monster>( newp ) ) {
1020 mon->apply_damage( nullptr, bodypart_id( "torso" ),
1021 6 - mon->get_armor_bash( bodypart_id( "torso" ) ) );
1022 if( g->u.sees( newp ) ) {
1023 add_msg( _( "A %1$s hits the %2$s!" ), tmp.tname(), mon->name() );
1024 }
1025 mon->check_dead_state();
1026 }
1027 }
1028 }
1029 }
1030 }
1031 if( cur_fd_type_id == fd_shock_vent ) {
1032 if( cur.get_field_intensity() > 1 ) {
1033 if( one_in( 5 ) ) {
1035 }
1036 } else {
1037 cur.set_field_intensity( 3 );
1038 int num_bolts = rng( 3, 6 );
1039 for( int i = 0; i < num_bolts; i++ ) {
1040 int xdir = 0;
1041 int ydir = 0;
1042 while( xdir == 0 && ydir == 0 ) {
1043 xdir = rng( -1, 1 );
1044 ydir = rng( -1, 1 );
1045 }
1046 int dist = rng( 4, 12 );
1047 int boltx = p.x;
1048 int bolty = p.y;
1049 for( int n = 0; n < dist; n++ ) {
1050 boltx += xdir;
1051 bolty += ydir;
1052 add_field( tripoint( boltx, bolty, p.z ), fd_electricity, rng( 2, 3 ) );
1053 if( one_in( 4 ) ) {
1054 if( xdir == 0 ) {
1055 xdir = rng( 0, 1 ) * 2 - 1;
1056 } else {
1057 xdir = 0;
1058 }
1059 }
1060 if( one_in( 4 ) ) {
1061 if( ydir == 0 ) {
1062 ydir = rng( 0, 1 ) * 2 - 1;
1063 } else {
1064 ydir = 0;
1065 }
1066 }
1067 }
1068 }
1069 }
1070 }
1071 if( cur_fd_type_id == fd_acid_vent ) {
1072
1073 if( cur.get_field_intensity() > 1 ) {
1074 if( cur.get_field_age() >= 1_minutes ) {
1076 cur.set_field_age( 0_turns );
1077 }
1078 } else {
1079 cur.set_field_intensity( 3 );
1080 for( const tripoint &t : points_in_radius( p, 5 ) ) {
1081 const field_entry *acid = get_field( t, fd_acid );
1082 if( acid != nullptr && acid->get_field_intensity() == 0 ) {
1083 int new_intensity = 3 - rl_dist( p, t ) / 2 + ( one_in( 3 ) ? 1 : 0 );
1084 if( new_intensity > 3 ) {
1085 new_intensity = 3;
1086 }
1087 if( new_intensity > 0 ) {
1088 add_field( t, fd_acid, new_intensity );
1089 }
1090 }
1091 }
1092 }
1093 }
1094 if( cur_fd_type_id == fd_bees ) {
1095 // Poor bees are vulnerable to so many other fields.
1096 // TODO: maybe adjust effects based on different fields.
1097 if( curfield.find_field( fd_web ) ||
1098 curfield.find_field( fd_fire ) ||
1099 curfield.find_field( fd_smoke ) ||
1100 curfield.find_field( fd_toxic_gas ) ||
1101 curfield.find_field( fd_tear_gas ) ||
1102 curfield.find_field( fd_relax_gas ) ||
1103 curfield.find_field( fd_nuke_gas ) ||
1104 curfield.find_field( fd_gas_vent ) ||
1105 curfield.find_field( fd_smoke_vent ) ||
1106 curfield.find_field( fd_fungicidal_gas ) ||
1107 curfield.find_field( fd_insecticidal_gas ) ||
1108 curfield.find_field( fd_fire_vent ) ||
1109 curfield.find_field( fd_flame_burst ) ||
1110 curfield.find_field( fd_electricity ) ||
1111 curfield.find_field( fd_fatigue ) ||
1112 curfield.find_field( fd_shock_vent ) ||
1113 curfield.find_field( fd_plasma ) ||
1114 curfield.find_field( fd_laser ) ||
1115 curfield.find_field( fd_dazzling ) ||
1116 curfield.find_field( fd_electricity ) ||
1117 curfield.find_field( fd_incendiary ) ) {
1118 // Kill them at the end of processing.
1119 cur.set_field_intensity( 0 );
1120 } else {
1121 // Bees chase the player if in range, wander randomly otherwise.
1122 if( !g->u.is_underwater() &&
1123 rl_dist( p, g->u.pos() ) < 10 &&
1124 clear_path( p, g->u.pos(), 10, 1, 100 ) ) {
1125
1126 std::vector<point> candidate_positions =
1127 squares_in_direction( p.xy(), point( g->u.posx(), g->u.posy() ) );
1128 for( const point &candidate_position : candidate_positions ) {
1129 field &target_field = get_field( tripoint( candidate_position, p.z ) );
1130 // Only shift if there are no bees already there.
1131 // TODO: Figure out a way to merge bee fields without allowing
1132 // Them to effectively move several times in a turn depending
1133 // on iteration direction.
1134 if( !target_field.find_field( fd_bees ) ) {
1135 add_field( tripoint( candidate_position, p.z ), fd_bees,
1136 cur.get_field_intensity(), cur.get_field_age() );
1137 cur.set_field_intensity( 0 );
1138 break;
1139 }
1140 }
1141 } else {
1142 spread_gas( cur, p, 5, 0_turns, sblk );
1143 }
1144 }
1145 }
1146 if( cur_fd_type_id == fd_incendiary ) {
1147 // Needed for variable scope
1148 tripoint dst( p + point( rng( -1, 1 ), rng( -1, 1 ) ) );
1149 if( has_flag( TFLAG_FLAMMABLE, dst ) ||
1150 has_flag( TFLAG_FLAMMABLE_ASH, dst ) ||
1151 has_flag( TFLAG_FLAMMABLE_HARD, dst ) ) {
1152 add_field( dst, fd_fire, 1 );
1153 }
1154
1155 // Check piles for flammable items and set those on fire
1156 if( flammable_items_at( dst ) ) {
1157 add_field( dst, fd_fire, 1 );
1158 }
1159
1161 }
1162 if( cur_fd_type_id == fd_fungicidal_gas ) {
1163 // Check the terrain and replace it accordingly to simulate the fungus dieing off
1164 const ter_t &ter = map_tile.get_ter_t();
1165 const furn_t &frn = map_tile.get_furn_t();
1166 const int intensity = cur.get_field_intensity();
1167 if( ter.has_flag( flag_FUNGUS ) && one_in( 10 / intensity ) ) {
1168 ter_set( p, t_dirt );
1169 }
1170 if( frn.has_flag( flag_FUNGUS ) && one_in( 10 / intensity ) ) {
1171 furn_set( p, f_null );
1172 }
1173 }
1174
1175 cur.set_field_age( cur.get_field_age() + 1_turns );
1176 auto &fdata = cur.get_field_type().obj();
1177 if( fdata.half_life > 0_turns && cur.get_field_age() > 0_turns &&
1178 dice( 2, to_turns<int>( cur.get_field_age() ) ) > to_turns<int>( fdata.half_life ) ) {
1179 cur.set_field_age( 0_turns );
1181 }
1182 if( !cur.is_field_alive() ) {
1183 --current_submap->field_count;
1184 curfield.remove_field( it++ );
1185 } else {
1186 ++it;
1187 }
1188 }
1189
1190 if( dirty_transparency_cache ) {
1192 set_seen_cache_dirty( thep );
1193 }
1194 }
1195 }
1196 const int minz = zlevels ? -OVERMAP_DEPTH : abs_sub.z;
1197 const int maxz = zlevels ? OVERMAP_HEIGHT : abs_sub.z;
1198 for( int z = std::max( submap.z - 1, minz ); z <= std::min( submap.z + 1, maxz ); ++z ) {
1199 auto &field_cache = get_cache( z ).field_cache;
1200 for( int y = std::max( submap.y - 1, 0 ); y <= std::min( submap.y + 1, MAPSIZE - 1 ); ++y ) {
1201 for( int x = std::max( submap.x - 1, 0 ); x <= std::min( submap.x + 1, MAPSIZE - 1 ); ++x ) {
1202 if( get_submap_at_grid( { x, y, z } )->field_count > 0 ) {
1203 field_cache.set( x + y * MAPSIZE );
1204 } else {
1205 field_cache.reset( x + y * MAPSIZE );
1206 }
1207 }
1208 }
1209 }
1210 sblk.commit_modifications();
1211}
bool gas_can_spread()
Definition: field.h:93
time_duration intensity_upgrade_duration() const
Definition: field.cpp:44
mongroup_id monster_spawn_group() const
Definition: field.cpp:64
time_duration get_underwater_age_speedup() const
Definition: field.h:97
int monster_spawn_count() const
Definition: field.cpp:54
time_duration mod_field_age(const time_duration &mod_age)
Adds given value to age.
Definition: field.h:73
int intensity_upgrade_chance() const
Definition: field.cpp:39
int monster_spawn_radius() const
Definition: field.cpp:59
int monster_spawn_chance() const
Definition: field.cpp:49
std::map< field_type_id, field_entry >::iterator begin()
Definition: field.cpp:251
std::map< field_type_id, field_entry >::iterator end()
Definition: field.cpp:261
void spread_fungus(const tripoint &p)
std::string tname(unsigned int quantity=1, bool with_prefix=true, unsigned int truncate=0) const
Return the (translated) item name.
Definition: item.cpp:4433
void set_age(const time_duration &age)
Definition: item.cpp:9826
bool detonate(const tripoint &p, std::vector< item > &drops)
Detonates the item and adds remains (if any) to drops.
Definition: item.cpp:8581
std::array< std::pair< tripoint, maptile >, 8 > get_neighbors(const tripoint &p)
Definition: map_field.cpp:190
void create_hot_air(const tripoint &p, int intensity)
Definition: map_field.cpp:361
bool clear_path(const tripoint &f, const tripoint &t, int range, int cost_min, int cost_max) const
Check whether there's a direct line of sight between F and T with the additional movecost restraints.
Definition: map.cpp:6360
void spread_gas(field_entry &cur, const tripoint &p, int percent_spread, const time_duration &outdoor_age_speedup, scent_block &sblk)
Definition: map_field.cpp:249
void create_burnproducts(const tripoint &p, const item &fuel, const units::mass &burned_mass)
Definition: map_field.cpp:96
field_type_id fd_laser
Definition: field_type.cpp:359
field_type_id fd_plasma
Definition: field_type.cpp:358
field_type_id fd_null
Definition: field_type.cpp:335
std::vector< point > squares_in_direction(const point &p1, const point &p2)
Definition: line.cpp:588
static const itype_id itype_rock("rock")
static bool check_flammable(const map_data_common_t &t)
Definition: map_field.cpp:352
static const std::string flag_FUNGUS("FUNGUS")
furn_id f_ash
Definition: mapdata.cpp:1097
ter_id t_pit
Definition: mapdata.cpp:625
@ TFLAG_FLAMMABLE_HARD
Definition: mapdata.h:294
@ TFLAG_FLAMMABLE
Definition: mapdata.h:277
@ TFLAG_FLAMMABLE_ASH
Definition: mapdata.h:289
@ TFLAG_FIRE_CONTAINER
Definition: mapdata.h:293
bool acid(monster *z)
Definition: monattack.cpp:581
bool get_transparent(int level=0) const
Definition: field_type.h:204
int percent_spread
Definition: field_type.h:157
field_type_id wandering_field
Definition: field_type.h:182
std::tuple< int, std::string, time_duration, std::string > npc_complain_data
Definition: field_type.h:170
time_duration outdoor_age_speedup
Definition: field_type.h:155
int apply_slime_factor
Definition: field_type.h:158
Contains the state of a fire in one tile on one turn.
Definition: fire.h:18
size_t get_item_count() const
Definition: submap.h:333
ter_id get_ter() const
Definition: submap.h:289

References _, abs_sub, mattack::acid(), add_field(), add_item_or_charges(), add_msg(), add_spawn(), adjust_radiation(), scent_block::apply_slime(), field_type::apply_slime_factor, field::begin(), item_stack::begin(), check_flammable(), clear_path(), scent_block::commit_modifications(), detail::count(), create_burnproducts(), create_hot_air(), vehicle::damage(), debugmsg, destroy(), destroyed, item::detonate(), dice(), field_type::dirty_transparency_cache, field::displayed_field_type(), DT_BASH, DT_HEAT, eight_horizontal_neighbors, field::end(), item_stack::end(), map_stack::erase(), explosive, field_entry::extra_radiation_max(), field_entry::extra_radiation_min(), f_ash, f_null, fd_acid, fd_acid_vent, fd_bees, fd_dazzling, fd_electricity, fd_fatigue, fd_fire, fd_fire_vent, fd_flame_burst, fd_fungal_haze, fd_fungicidal_gas, fd_gas_vent, fd_incendiary, fd_insecticidal_gas, fd_laser, fd_nuke_gas, fd_null, fd_plasma, fd_push_items, fd_relax_gas, fd_shock_vent, fd_smoke, fd_smoke_vent, fd_tear_gas, fd_toxic_gas, fd_web, field_at(), level_cache::field_cache, submap::field_count, maptile::find_field(), field::find_field(), flag_FUNGUS(), flammable_items_at(), fire_data::fuel_produced, furn_set(), g, field_entry::gas_can_spread(), get_cache(), submap::get_field(), get_field(), field_entry::get_field_age(), field_entry::get_field_intensity(), field_entry::get_field_type(), maptile::get_furn_t(), maptile::get_item_count(), get_map(), get_neighbors(), get_submap_at_grid(), maptile::get_ter(), maptile::get_ter_t(), field_type::get_transparent(), field_entry::get_underwater_age_speedup(), MonsterGroupManager::GetResultFromGroup(), map_data_common_t::has_flag(), has_flag(), i_at(), int_id< T >::id(), ter_t::id, string_id< T >::id(), impassable(), field_entry::intensity_upgrade_chance(), field_entry::intensity_upgrade_duration(), field_entry::is_field_alive(), itype_rock, m_bad, MAPSIZE, maptile_at_internal(), field_entry::mod_field_age(), field_entry::monster_spawn_chance(), field_entry::monster_spawn_count(), field_entry::monster_spawn_group(), field_entry::monster_spawn_radius(), MonsterGroupResult::name, field_type::npc_complain_data, int_id< T >::obj(), calendar::once_every(), one_in(), field_type::outdoor_age_speedup, OVERMAP_DEPTH, OVERMAP_HEIGHT, MonsterGroupResult::pack_size, passable(), field_type::percent_spread, point_zero, points_in_radius(), maptile::pos_, random_entry(), random_entry_removed(), random_point(), field::remove_field(), rl_dist(), rng(), roll_remainder(), SEEX, SEEY, item::set_age(), field_entry::set_field_age(), field_entry::set_field_intensity(), set_seen_cache_dirty(), set_transparency_cache_dirty(), spawn_items(), fungal_effects::spread_fungus(), spread_gas(), squares_in_direction(), t_dirt, t_open_air, t_pit, ter(), ter_furn_has_flag(), ter_set(), TFLAG_ALLOW_FIELD_EFFECT, TFLAG_FIRE_CONTAINER, TFLAG_FLAMMABLE, TFLAG_FLAMMABLE_ASH, TFLAG_FLAMMABLE_HARD, TFLAG_NO_FLOOR, TFLAG_SEALED, TFLAG_SWIMMABLE, item::tname(), valid_move(), veh_at_internal(), field_type::wandering_field, point::x, tripoint::x, tripoint::xy(), point::y, tripoint::y, tripoint::z, and zlevels.

Referenced by process_fields().

◆ process_items()

void map::process_items ( )

Definition at line 4559 of file map.cpp.

4560{
4561 const int minz = zlevels ? -OVERMAP_DEPTH : abs_sub.z;
4562 const int maxz = zlevels ? OVERMAP_HEIGHT : abs_sub.z;
4563 for( int gz = minz; gz <= maxz; ++gz ) {
4564 level_cache &cache = access_cache( gz );
4565 std::set<tripoint> submaps_with_vehicles;
4566 for( vehicle *this_vehicle : cache.vehicle_list ) {
4567 tripoint pos = this_vehicle->global_pos3();
4568 submaps_with_vehicles.emplace( pos.x / SEEX, pos.y / SEEY, pos.z );
4569 }
4570 for( const tripoint &pos : submaps_with_vehicles ) {
4571 submap *const current_submap = get_submap_at_grid( pos );
4572 // Vehicles first in case they get blown up and drop active items on the map.
4573 process_items_in_vehicles( *current_submap );
4574 }
4575 }
4576 // Making a copy, in case the original variable gets modified during `process_items_in_submap`
4577 const std::set<tripoint> submaps_with_active_items_copy = submaps_with_active_items;
4578 for( const tripoint &abs_pos : submaps_with_active_items_copy ) {
4579 const tripoint local_pos = abs_pos - abs_sub.xy();
4580 submap *const current_submap = get_submap_at_grid( local_pos );
4581 if( !current_submap->active_items.empty() ) {
4582 process_items_in_submap( *current_submap, local_pos );
4583 }
4584 }
4585}
void process_items_in_vehicles(submap &current_submap)
Definition: map.cpp:4617
void process_items_in_submap(submap &current_submap, const tripoint &gridp)
Definition: map.cpp:4587

References abs_sub, access_cache(), submap::active_items, active_item_cache::empty(), get_submap_at_grid(), vehicle::global_pos3(), OVERMAP_DEPTH, OVERMAP_HEIGHT, wrapped_vehicle::pos, process_items_in_submap(), process_items_in_vehicles(), SEEX, SEEY, submaps_with_active_items, level_cache::vehicle_list, tripoint::x, tripoint::xy(), tripoint::y, tripoint::z, and zlevels.

Referenced by game::do_turn().

◆ process_items_in_submap()

void map::process_items_in_submap ( submap current_submap,
const tripoint gridp 
)
private

Definition at line 4587 of file map.cpp.

4588{
4589 // Get a COPY of the active item list for this submap.
4590 // If more are added as a side effect of processing, they are ignored this turn.
4591 // If they are destroyed before processing, they don't get processed.
4592 std::vector<item_reference> active_items = current_submap.active_items.get_for_processing();
4593 const point grid_offset( gridp.x * SEEX, gridp.y * SEEY );
4594 for( item_reference &active_item_ref : active_items ) {
4595 if( !active_item_ref.item_ref ) {
4596 // The item was destroyed, so skip it.
4597 continue;
4598 }
4599
4600 const tripoint map_location = tripoint( grid_offset + active_item_ref.location, gridp.z );
4601 // root cellars are special
4603 if( ter( map_location ) == t_rootcellar ) {
4605 }
4606 if( furn( map_location ) == f_fridge_on ) {
4608 }
4609 if( furn( map_location ) == f_minifreezer_on ) {
4611 }
4612 map_stack items = i_at( map_location );
4613 process_map_items( items, active_item_ref.item_ref, map_location, 1, flag );
4614 }
4615}
std::vector< item_reference > get_for_processing()
Returns the first size() / processing_speed() elements of each list, rounded up.
temperature_flag
Definition: enums.h:42
@ TEMP_NORMAL
Definition: enums.h:43
@ TEMP_FRIDGE
Definition: enums.h:45
@ TEMP_FREEZER
Definition: enums.h:46
@ TEMP_ROOT_CELLAR
Definition: enums.h:47
static bool process_map_items(item_stack &items, safe_reference< item > &item_ref, const tripoint &location, const float insulation, const temperature_flag flag)
Definition: map.cpp:4445
ter_id t_rootcellar
Definition: mapdata.cpp:711
furn_id f_minifreezer_on
Definition: mapdata.cpp:1106
furn_id f_fridge_on
Definition: mapdata.cpp:1106

References submap::active_items, f_fridge_on, f_minifreezer_on, furn(), active_item_cache::get_for_processing(), i_at(), process_map_items(), SEEX, SEEY, t_rootcellar, TEMP_FREEZER, TEMP_FRIDGE, TEMP_NORMAL, TEMP_ROOT_CELLAR, ter(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by process_items().

◆ process_items_in_vehicle()

void map::process_items_in_vehicle ( vehicle cur_veh,
submap current_submap 
)
private

Definition at line 4638 of file map.cpp.

4639{
4640 const bool engine_heater_is_on = cur_veh.has_part( "E_HEATER", true ) && cur_veh.engine_on;
4641 for( const vpart_reference &vp : cur_veh.get_any_parts( VPFLAG_FLUIDTANK ) ) {
4642 vp.part().process_contents( vp.pos(), engine_heater_is_on );
4643 }
4644
4645 auto cargo_parts = cur_veh.get_parts_including_carried( VPFLAG_CARGO );
4646 for( const vpart_reference &vp : cargo_parts ) {
4647 process_vehicle_items( cur_veh, vp.part_index() );
4648 }
4649
4650 for( item_reference &active_item_ref : cur_veh.active_items.get_for_processing() ) {
4651 if( empty( cargo_parts ) ) {
4652 return;
4653 } else if( !active_item_ref.item_ref ) {
4654 // The item was destroyed, so skip it.
4655 continue;
4656 }
4657 const auto it = std::find_if( begin( cargo_parts ),
4658 end( cargo_parts ), [&]( const vpart_reference & part ) {
4659 return active_item_ref.location == part.mount();
4660 } );
4661
4662 if( it == end( cargo_parts ) ) {
4663 continue; // Can't find a cargo part matching the active item.
4664 }
4665 const item &target = *active_item_ref.item_ref;
4666 // Find the cargo part and coordinates corresponding to the current active item.
4667 const vehicle_part &pt = it->part();
4668 const tripoint item_loc = it->pos();
4669 auto items = cur_veh.get_items( static_cast<int>( it->part_index() ) );
4670 float it_insulation = 1.0;
4672 if( target.is_food() || target.is_food_container() || target.is_corpse() ) {
4673 const vpart_info &pti = pt.info();
4674 if( engine_heater_is_on ) {
4676 }
4677 // some vehicle parts provide insulation, default is 1
4678 it_insulation = pti.item->insulation_factor;
4679
4680 if( pt.enabled && pti.has_flag( VPFLAG_FRIDGE ) ) {
4681 it_insulation = 1; // ignore fridge insulation if on
4683 } else if( pt.enabled && pti.has_flag( VPFLAG_FREEZER ) ) {
4684 it_insulation = 1; // ignore freezer insulation if on
4686 }
4687 }
4688 if( !process_map_items( items, active_item_ref.item_ref, item_loc, it_insulation, flag ) ) {
4689 // If the item was NOT destroyed, we can skip the remainder,
4690 // which handles fallout from the vehicle being damaged.
4691 continue;
4692 }
4693
4694 // item does not exist anymore, might have been an exploding bomb,
4695 // check if the vehicle is still valid (does exist)
4696 if( !current_submap.contains_vehicle( &cur_veh ) ) {
4697 // Nope, vehicle is not in the vehicle list of the submap,
4698 // it might have moved to another submap (unlikely)
4699 // or be destroyed, anyway it does not need to be processed here
4700 return;
4701 }
4702
4703 // Vehicle still valid, reload the list of cargo parts,
4704 // the list of cargo parts might have changed (imagine a part with
4705 // a low index has been removed by an explosion, all the other
4706 // parts would move up to fill the gap).
4707 cargo_parts = cur_veh.get_any_parts( VPFLAG_CARGO );
4708 }
4709}
bool is_food_container() const
Definition: item.cpp:6447
bool is_corpse() const
Whether this is a corpse item.
Definition: item.cpp:6459
bool contains_vehicle(vehicle *)
Definition: submap.cpp:220
bool engine_on
Definition: vehicle.h:1969
vehicle_part_with_feature_range< std::string > get_parts_including_carried(std::string feature) const
Yields a range of parts of this vehicle that each have the given feature and are not broken or remove...
Definition: vehicle.cpp:2696
bool has_part(const std::string &flag, bool enabled=false) const
Check if vehicle has at least one unbroken part with specified flag.
Definition: vehicle.cpp:2560
active_item_cache active_items
Definition: vehicle.h:1844
vehicle_part_with_feature_range< std::string > get_any_parts(std::string feature) const
Yields a range of parts of this vehicle that each have the given feature and not removed.
Definition: vehicle.cpp:2710
itype_id item
base item for this part
Definition: veh_type.h:152
point mount() const
Returns the mount point: the point in the vehicles own coordinate system.
Definition: vehicle.cpp:6610
@ TEMP_HEATER
Definition: enums.h:44
static void process_vehicle_items(vehicle &cur_veh, int part)
Definition: map.cpp:4460
float insulation_factor
How much insulation this item provides, either as a container, or as a vehicle base part.
Definition: itype.h:1035
const vpart_info & info() const
Get part definition common to all parts of this type.
bool enabled
Definition: vehicle.h:411
@ VPFLAG_FLUIDTANK
Definition: veh_type.h:73
@ VPFLAG_FREEZER
Definition: veh_type.h:58
@ VPFLAG_FRIDGE
Definition: veh_type.h:57

References vehicle::active_items, submap::contains_vehicle(), vehicle_part::enabled, vehicle::engine_on, vehicle::get_any_parts(), active_item_cache::get_for_processing(), vehicle::get_items(), vehicle::get_parts_including_carried(), vpart_info::has_flag(), vehicle::has_part(), vehicle_part::info(), itype::insulation_factor, item::is_corpse(), item::is_food(), item::is_food_container(), vpart_info::item, vpart_position::mount(), process_map_items(), process_vehicle_items(), TEMP_FREEZER, TEMP_FRIDGE, TEMP_HEATER, TEMP_NORMAL, VPFLAG_CARGO, VPFLAG_FLUIDTANK, VPFLAG_FREEZER, and VPFLAG_FRIDGE.

Referenced by process_items_in_vehicles().

◆ process_items_in_vehicles()

void map::process_items_in_vehicles ( submap current_submap)
private

Definition at line 4617 of file map.cpp.

4618{
4619 // a copy, important if the vehicle list changes because a
4620 // vehicle got destroyed by a bomb (an active item!), this list
4621 // won't change, but veh_in_nonant will change.
4622 std::vector<vehicle *> vehicles;
4623 for( const auto &veh : current_submap.vehicles ) {
4624 vehicles.push_back( veh.get() );
4625 }
4626 for( auto &cur_veh : vehicles ) {
4627 if( !current_submap.contains_vehicle( cur_veh ) ) {
4628 // vehicle not in the vehicle list of the nonant, has been
4629 // destroyed (or moved to another nonant?)
4630 // Can't be sure that it still exists, so skip it
4631 continue;
4632 }
4633
4634 process_items_in_vehicle( *cur_veh, current_submap );
4635 }
4636}
void process_items_in_vehicle(vehicle &cur_veh, submap &current_submap)
Definition: map.cpp:4638

References submap::contains_vehicle(), process_items_in_vehicle(), and submap::vehicles.

Referenced by process_items().

◆ produce_sap()

void map::produce_sap ( const tripoint p,
const time_duration time_since_last_actualize 
)
protected

Produce sap on tapped maple trees.

Parameters
pLocation of tapped tree
time_since_last_actualizeTime since this function has been called the last time.

Definition at line 7101 of file map.cpp.

7102{
7103 if( time_since_last_actualize <= 0_turns ) {
7104 return;
7105 }
7106
7107 if( t_tree_maple_tapped != ter( p ) ) {
7108 return;
7109 }
7110
7111 // Amount of maple sap liters produced per season per tap
7112 static const int maple_sap_per_season = 56;
7113
7114 // How many turns to produce 1 charge (250 ml) of sap?
7115 const time_duration producing_length = 0.75 * calendar::season_length();
7116
7117 const time_duration turns_to_produce = producing_length / ( maple_sap_per_season * 4 );
7118
7119 // How long of this time_since_last_actualize have we been in the producing period (late winter, early spring)?
7120 time_duration time_producing = 0_turns;
7121
7122 if( time_since_last_actualize >= calendar::year_length() ) {
7123 time_producing = producing_length;
7124 } else {
7125 // We are only producing sap on the intersection with the sap producing season.
7126 const time_duration early_spring_end = 0.5f * calendar::season_length();
7127 const time_duration late_winter_start = 3.75f * calendar::season_length();
7128
7129 const time_point last_actualize = calendar::turn - time_since_last_actualize;
7130 const time_duration last_actualize_tof = time_past_new_year( last_actualize );
7131 bool last_producing = (
7132 last_actualize_tof >= late_winter_start ||
7133 last_actualize_tof < early_spring_end
7134 );
7135 const time_duration current_tof = time_past_new_year( calendar::turn );
7136 bool current_producing = (
7137 current_tof >= late_winter_start ||
7138 current_tof < early_spring_end
7139 );
7140
7141 const time_duration non_producing_length = 3.25 * calendar::season_length();
7142
7143 if( last_producing && current_producing ) {
7144 if( time_since_last_actualize < non_producing_length ) {
7145 time_producing = time_since_last_actualize;
7146 } else {
7147 time_producing = time_since_last_actualize - non_producing_length;
7148 }
7149 } else if( !last_producing && !current_producing ) {
7150 if( time_since_last_actualize > non_producing_length ) {
7151 time_producing = time_since_last_actualize - non_producing_length;
7152 }
7153 } else if( last_producing && !current_producing ) {
7154 // We hit the end of early spring
7155 if( last_actualize_tof < early_spring_end ) {
7156 time_producing = early_spring_end - last_actualize_tof;
7157 } else {
7158 time_producing = calendar::year_length() - last_actualize_tof + early_spring_end;
7159 }
7160 } else if( !last_producing && current_producing ) {
7161 // We hit the start of late winter
7162 if( current_tof >= late_winter_start ) {
7163 time_producing = current_tof - late_winter_start;
7164 } else {
7165 time_producing = 0.25f * calendar::season_length() + current_tof;
7166 }
7167 }
7168 }
7169
7170 int new_charges = roll_remainder( time_producing / turns_to_produce );
7171 // Not enough time to produce 1 charge of sap
7172 if( new_charges <= 0 ) {
7173 return;
7174 }
7175
7176 item sap( "maple_sap", calendar::turn );
7177
7178 // Is there a proper container?
7179 auto items = i_at( p );
7180 for( auto &it : items ) {
7181 if( it.is_bucket() || it.is_watertight_container() ) {
7182 const int capacity = it.get_remaining_capacity_for_liquid( sap, true );
7183 if( capacity > 0 ) {
7184 new_charges = std::min( new_charges, capacity );
7185
7186 // The environment might have poisoned the sap with animals passing by, insects, leaves or contaminants in the ground
7187 sap.poison = one_in( 10 ) ? 1 : 0;
7188 sap.charges = new_charges;
7189
7190 it.fill_with( sap );
7191 }
7192 // Only fill up the first container.
7193 break;
7194 }
7195 }
7196}
time_duration time_past_new_year(const time_point &p)
Definition: calendar.h:502
A point in the game time.
Definition: calendar.h:431
ter_id t_tree_maple_tapped
Definition: mapdata.cpp:681
time_duration year_length()
Definition: calendar.cpp:461
time_duration season_length()
Definition: calendar.cpp:466

References item::charges, i_at(), one_in(), item::poison, roll_remainder(), calendar::season_length(), t_tree_maple_tapped, ter(), time_past_new_year(), calendar::turn, and calendar::year_length().

Referenced by actualize().

◆ propagate_field()

void map::propagate_field ( const tripoint center,
const field_type_id type,
int  amount,
int  max_intensity = 0 
)

Definition at line 1938 of file map_field.cpp.

1940{
1941 using gas_blast = std::pair<float, tripoint>;
1942 std::priority_queue<gas_blast, std::vector<gas_blast>, pair_greater_cmp_first> open;
1943 std::set<tripoint> closed;
1944 open.push( { 0.0f, center } );
1945
1946 const bool not_gas = type.obj().phase != GAS;
1947
1948 while( amount > 0 && !open.empty() ) {
1949 if( closed.count( open.top().second ) ) {
1950 open.pop();
1951 continue;
1952 }
1953
1954 // All points with equal gas intensity should propagate at the same time
1955 std::list<gas_blast> gas_front;
1956 gas_front.push_back( open.top() );
1957 const int cur_intensity = get_field_intensity( open.top().second, type );
1958 open.pop();
1959 while( !open.empty() && get_field_intensity( open.top().second, type ) == cur_intensity ) {
1960 if( closed.count( open.top().second ) == 0 ) {
1961 gas_front.push_back( open.top() );
1962 }
1963
1964 open.pop();
1965 }
1966
1967 int increment = std::max<int>( 1, amount / gas_front.size() );
1968
1969 while( !gas_front.empty() ) {
1970 gas_blast gp = random_entry_removed( gas_front );
1971 closed.insert( gp.second );
1972 const int cur_intensity = get_field_intensity( gp.second, type );
1973 if( cur_intensity < max_intensity ) {
1974 const int bonus = std::min( max_intensity - cur_intensity, increment );
1975 mod_field_intensity( gp.second, type, bonus );
1976 amount -= bonus;
1977 } else {
1978 amount--;
1979 }
1980
1981 if( amount <= 0 ) {
1982 return;
1983 }
1984
1985 static const std::array<int, 8> x_offset = {{ -1, 1, 0, 0, 1, -1, -1, 1 }};
1986 static const std::array<int, 8> y_offset = {{ 0, 0, -1, 1, -1, 1, -1, 1 }};
1987 for( size_t i = 0; i < 8; i++ ) {
1988 tripoint pt = gp.second + point( x_offset[ i ], y_offset[ i ] );
1989 if( closed.count( pt ) > 0 ) {
1990 continue;
1991 }
1992
1993 if( impassable( pt ) && ( not_gas || !has_flag( TFLAG_PERMEABLE, pt ) ) ) {
1994 closed.insert( pt );
1995 continue;
1996 }
1997
1998 open.push( { static_cast<float>( rl_dist( center, pt ) ), pt } );
1999 }
2000 }
2001 }
2002}
@ GAS
Definition: enums.h:175
Greater-than comparison operator; required by the sort interface.
Definition: cata_utility.h:16

References center, GAS, get_field_intensity(), has_flag(), impassable(), mod_field_intensity(), open(), random_entry_removed(), rl_dist(), TFLAG_PERMEABLE, and type.

Referenced by computer_session::action_irradiator(), and emit_field().

◆ propagate_suspension_check()

void map::propagate_suspension_check ( const tripoint point)

Checks surrounding tiles for suspension, and has them check for collapse.

!!Should only be called after the tile at this point has been destroyed!!

Definition at line 2938 of file map.cpp.

2939{
2940 for( const tripoint &neighbor : points_in_radius( point, 1 ) ) {
2941 if( neighbor != point && has_flag( TFLAG_SUSPENDED, neighbor ) ) {
2942 collapse_invalid_suspension( neighbor );
2943 }
2944 }
2945}

References collapse_invalid_suspension(), has_flag(), points_in_radius(), and TFLAG_SUSPENDED.

Referenced by bash_ter_success(), collapse_at(), and collapse_invalid_suspension().

◆ put_items_from_loc()

std::vector< item * > map::put_items_from_loc ( const item_group_id loc,
const tripoint p,
const time_point turn = calendar::start_of_cataclysm 
)

Place items from an item group at p.

Places as much items as the item group says. (Most item groups are distributions and will only create one item.)

Parameters
locCurrent location of items
pDestination of items
turnThe birthday that the created items shall have.
Returns
Vector of pointers to placed items (can be empty, but no nulls).

Definition at line 5571 of file mapgen.cpp.

5573{
5574 const auto items = item_group::items_from( loc, turn );
5575 return spawn_items( p, items );
5576}

References item_group::items_from(), spawn_items(), and calendar::turn.

Referenced by add_corpse(), activity_handlers::forage_finish(), mapgen_cavern(), MapExtras::mx_corpses(), MapExtras::mx_grave(), MapExtras::mx_mayhem(), MapExtras::mx_minefield(), and place_items().

◆ rad_scorch()

void map::rad_scorch ( const tripoint p,
const time_duration time_since_last_actualize 
)
protected

Radiation-related plant (and fungus?) death.

Definition at line 7198 of file map.cpp.

7199{
7200 const int rads = get_radiation( p );
7201 if( rads == 0 ) {
7202 return;
7203 }
7204
7205 // TODO: More interesting rad scorch chance - base on season length?
7206 if( !x_in_y( 1.0 * rads * rads * time_since_last_actualize, 91_days ) ) {
7207 return;
7208 }
7209
7210 // First destroy the farmable plants (those are furniture)
7211 // TODO: Rad-resistant mutant plants (that produce radioactive fruit)
7212 const furn_t &fid = furn( p ).obj();
7213 if( fid.has_flag( "PLANT" ) ) {
7214 i_clear( p );
7215 furn_set( p, f_null );
7216 }
7217
7218 const ter_id tid = ter( p );
7219 // TODO: De-hardcode this
7220 static const std::map<ter_id, ter_str_id> dies_into {{
7221 {t_grass, ter_str_id( "t_dirt" )},
7222 {t_tree_young, ter_str_id( "t_dirt" )},
7223 {t_tree_pine, ter_str_id( "t_tree_deadpine" )},
7224 {t_tree_birch, ter_str_id( "t_tree_birch_harvested" )},
7225 {t_tree_willow, ter_str_id( "t_tree_willow_harvested" )},
7226 {t_tree_hickory, ter_str_id( "t_tree_hickory_dead" )},
7227 {t_tree_hickory_harvested, ter_str_id( "t_tree_hickory_dead" )},
7228 }};
7229
7230 const auto iter = dies_into.find( tid );
7231 if( iter != dies_into.end() ) {
7232 ter_set( p, iter->second );
7233 return;
7234 }
7235
7236 const ter_t &tr = tid.obj();
7237 if( tr.has_flag( "SHRUB" ) ) {
7238 ter_set( p, t_dirt );
7239 } else if( tr.has_flag( "TREE" ) ) {
7240 ter_set( p, ter_str_id( "t_tree_dead" ) );
7241 }
7242}
int get_radiation(const tripoint &p) const
Definition: map.cpp:4013
ter_id t_tree_hickory_harvested
Definition: mapdata.cpp:682
ter_id t_tree_willow
Definition: mapdata.cpp:681
ter_id t_tree_birch
Definition: mapdata.cpp:681
ter_id t_tree_pine
Definition: mapdata.cpp:681
ter_id t_tree_young
Definition: mapdata.cpp:677
ter_id t_tree_hickory
Definition: mapdata.cpp:682
string_id< ter_t > ter_str_id
Definition: mapdata.h:24

References f_null, furn(), furn_set(), get_radiation(), map_data_common_t::has_flag(), i_clear(), int_id< T >::obj(), t_dirt, t_grass, t_tree_birch, t_tree_hickory, t_tree_hickory_harvested, t_tree_pine, t_tree_willow, t_tree_young, ter(), ter_set(), and x_in_y().

Referenced by actualize().

◆ random_outdoor_tile()

point map::random_outdoor_tile ( )

Definition at line 2725 of file map.cpp.

2726{
2727 std::vector<point> options;
2728 for( const tripoint &p : points_on_zlevel() ) {
2729 if( is_outside( p.xy() ) ) {
2730 options.push_back( p.xy() );
2731 }
2732 }
2734}
std::string options()
Definition: path_info.cpp:238

References is_outside(), PATH_INFO::options(), point_north_west, points_on_zlevel(), and random_entry().

◆ ranged_target_size()

double map::ranged_target_size ( const tripoint p) const

Size of map objects at p for purposes of ranged combat.

Size is in percentage of tile: if 1.0, all attacks going through tile should hit map objects on it, if 0.0 there is nothing to be hit (air/water).

Definition at line 1950 of file map.cpp.

1951{
1952 if( impassable( p ) ) {
1953 return 1.0;
1954 }
1955
1956 if( !has_floor( p ) ) {
1957 return 0.0;
1958 }
1959
1960 // TODO: Handle cases like shrubs, trees, furniture, sandbags...
1961 return 0.1;
1962}

References has_floor(), and impassable().

Referenced by projectile_attack().

◆ reachable_flood_steps()

void map::reachable_flood_steps ( std::vector< tripoint > &  reachable_pts,
const tripoint f,
int  range,
int  cost_min,
int  cost_max 
) const

Populates a vector of points that are reachable within a number of steps from a point.

It could be generalized to take advantage of z levels, but would need some additional code to detect whether a valid transition was on a tile.

Does the following:

  1. Checks if a point is reachable using a flood fill and if it is, adds it to a vector.

Definition at line 6250 of file map.cpp.

6252{
6253 struct pq_item {
6254 int dist;
6255 int ndx;
6256 };
6257 struct pq_item_comp {
6258 bool operator()( const pq_item &left, const pq_item &right ) {
6259 return left.dist > right.dist;
6260 }
6261 };
6262 using PQ_type = std::priority_queue< pq_item, std::vector<pq_item>, pq_item_comp>;
6263
6264 // temp buffer for grid
6265 const int grid_dim = range * 2 + 1;
6266 // init to -1 as "not visited yet"
6267 std::vector< int > t_grid( static_cast<size_t>( grid_dim * grid_dim ), -1 );
6268 const tripoint origin_offset = {range, range, 0};
6269 const int initial_visit_distance = range * range; // Large unreachable value
6270
6271 // Fill positions that are visitable with initial_visit_distance
6272 for( const tripoint &p : points_in_radius( f, range ) ) {
6273 const tripoint tp = { p.xy(), f.z };
6274 const int tp_cost = move_cost( tp );
6275 // rejection conditions
6276 if( tp_cost < cost_min || tp_cost > cost_max || !has_floor_or_support( tp ) ) {
6277 continue;
6278 }
6279 // set initial cost for grid point
6280 tripoint origin_relative = tp - f;
6281 origin_relative += origin_offset;
6282 int ndx = origin_relative.x + origin_relative.y * grid_dim;
6283 t_grid[ ndx ] = initial_visit_distance;
6284 }
6285
6286 auto gen_neighbors = []( const pq_item & elem, int grid_dim, pq_item * neighbors ) {
6287 // Up to 8 neighbors
6288 int new_cost = elem.dist + 1;
6289 // *INDENT-OFF*
6290 int ox[8] = {
6291 -1, 0, 1,
6292 -1, 1,
6293 -1, 0, 1
6294 };
6295 int oy[8] = {
6296 -1, -1, -1,
6297 0, 0,
6298 1, 1, 1
6299 };
6300 // *INDENT-ON*
6301
6302 point e( elem.ndx % grid_dim, elem.ndx / grid_dim );
6303 for( int i = 0; i < 8; ++i ) {
6304 point n( e + point( ox[i], oy[i] ) );
6305
6306 int ndx = n.x + n.y * grid_dim;
6307 neighbors[i] = { new_cost, ndx };
6308 }
6309 };
6310
6311 PQ_type pq( pq_item_comp{} );
6312 pq_item first_item{ 0, range + range * grid_dim };
6313 pq.push( first_item );
6314 pq_item neighbor_elems[8];
6315
6316 while( !pq.empty() ) {
6317 const pq_item item = pq.top();
6318 pq.pop();
6319
6320 if( t_grid[ item.ndx ] == initial_visit_distance ) {
6321 t_grid[ item.ndx ] = item.dist;
6322 if( item.dist + 1 < range ) {
6323 gen_neighbors( item, grid_dim, neighbor_elems );
6324 for( pq_item neighbor_elem : neighbor_elems ) {
6325 pq.push( neighbor_elem );
6326 }
6327 }
6328 }
6329 }
6330 std::vector<char> o_grid( static_cast<size_t>( grid_dim * grid_dim ), 0 );
6331 for( int y = 0, ndx = 0; y < grid_dim; ++y ) {
6332 for( int x = 0; x < grid_dim; ++x, ++ndx ) {
6333 if( t_grid[ ndx ] != -1 && t_grid[ ndx ] < initial_visit_distance ) {
6334 // set self and neighbors to 1
6335 for( int dy = -1; dy <= 1; ++dy ) {
6336 for( int dx = -1; dx <= 1; ++dx ) {
6337 int tx = dx + x;
6338 int ty = dy + y;
6339
6340 if( tx >= 0 && tx < grid_dim && ty >= 0 && ty < grid_dim ) {
6341 o_grid[ tx + ty * grid_dim ] = 1;
6342 }
6343 }
6344 }
6345 }
6346 }
6347 }
6348
6349 // Now go over again to pull out all of the reachable points
6350 for( int y = 0, ndx = 0; y < grid_dim; ++y ) {
6351 for( int x = 0; x < grid_dim; ++x, ++ndx ) {
6352 if( o_grid[ ndx ] ) {
6353 tripoint t = f - origin_offset + tripoint{ x, y, 0 };
6354 reachable_pts.push_back( t );
6355 }
6356 }
6357 }
6358}

References has_floor_or_support(), left, move_cost(), points_in_radius(), right, point::x, tripoint::x, tripoint::xy(), point::y, tripoint::y, and tripoint::z.

Referenced by inventory::form_from_map(), and use_charges().

◆ register_vehicle_zone()

void map::register_vehicle_zone ( vehicle veh,
int  zlev 
)

Definition at line 952 of file map.cpp.

953{
954 auto &ch = get_cache( zlev );
955 ch.zone_vehicles.insert( veh );
956}

References get_cache().

Referenced by zone_manager::create_vehicle_loot_zone(), and zone_manager::revert_vzones().

◆ remove_field()

void map::remove_field ( const tripoint p,
const field_type_id field_to_remove 
)

Remove field entry at xy, ignored if the field entry is not present.

Definition at line 5443 of file map.cpp.

5444{
5445 if( !inbounds( p ) ) {
5446 return;
5447 }
5448
5449 point l;
5450 submap *const current_submap = get_submap_at( p, l );
5451
5452 if( current_submap->get_field( l ).remove_field( field_to_remove ) ) {
5453 // Only adjust the count if the field actually existed.
5454 if( !--current_submap->field_count ) {
5455 get_cache( p.z ).field_cache.set( static_cast<size_t>( p.x / SEEX + ( (
5456 p.y / SEEX ) * MAPSIZE ) ) );
5457 }
5458 const auto &fdata = field_to_remove.obj();
5459 if( fdata.dirty_transparency_cache || !fdata.is_transparent() ) {
5462 }
5463 if( fdata.is_dangerous() ) {
5465 }
5466 }
5467}

References level_cache::field_cache, submap::field_count, get_cache(), submap::get_field(), get_submap_at(), inbounds(), MAPSIZE, int_id< T >::obj(), field::remove_field(), SEEX, set_pathfinding_cache_dirty(), set_seen_cache_dirty(), set_transparency_cache_dirty(), tripoint::x, tripoint::y, and tripoint::z.

Referenced by computer_session::action_deactivate_shock_vent(), bash_field(), editmap::edit_fld(), iexamine::fireplace(), game::grabbed_furn_move(), MapExtras::mx_house_spider(), MapExtras::mx_spider(), game::process_artifact(), set_field_intensity(), shoot(), smash(), and game::walk_move().

◆ remove_rotten_items()

template<typename Container >
void map::remove_rotten_items ( Container &  items,
const tripoint p 
)
protected

Go through the list of items, update their rotten status and remove items that have rotten away completely.

Parameters
itemsitems to remove
pThe point on this map where the items are, used for rot calculation.

Definition at line 6947 of file map.cpp.

6948{
6949 for( auto it = items.begin(); it != items.end(); ) {
6950 if( it->has_rotten_away( pnt ) ) {
6951 if( it->is_comestible() ) {
6952 rotten_item_spawn( *it, pnt );
6953 }
6954 it = i_rem( pnt, it );
6955 } else {
6956 ++it;
6957 }
6958 }
6959}

References i_rem(), and rotten_item_spawn().

Referenced by actualize().

◆ remove_submap_camp()

void map::remove_submap_camp ( const tripoint p)

Definition at line 5546 of file map.cpp.

5547{
5548 get_submap_at( p )->camp.reset();
5549}

References submap::camp, and get_submap_at().

Referenced by basecamp::abandon_camp(), and game::validate_camps().

◆ remove_trap()

void map::remove_trap ( const tripoint p)

Definition at line 5251 of file map.cpp.

5252{
5253 if( !inbounds( p ) ) {
5254 return;
5255 }
5256
5257 point l;
5258 submap *const current_submap = get_submap_at( p, l );
5259
5260 trap_id tid = current_submap->get_trap( l );
5261 if( tid != tr_null ) {
5262 if( g != nullptr && this == &get_map() ) {
5263 g->u.add_known_trap( p, tr_null.obj() );
5264 }
5265
5266 current_submap->set_trap( l, tr_null );
5267 auto &traps = traplocs[tid.to_i()];
5268 const auto iter = std::find( traps.begin(), traps.end(), p );
5269 if( iter != traps.end() ) {
5270 traps.erase( iter );
5271 }
5272 }
5273}
void set_trap(const point &p, trap_id trap)
Definition: submap.h:77
FMT_CONSTEXPR bool find(Ptr first, Ptr last, T value, Ptr &out)

References detail::find(), g, get_map(), get_submap_at(), submap::get_trap(), inbounds(), int_id< T >::obj(), submap::set_trap(), int_id< T >::to_i(), tr_null, and traplocs.

Referenced by complete_construction(), vehicle::handle_trap(), trapfunc::map_regen(), mremove_trap(), trap::on_disarmed(), game::process_artifact(), and trap_set().

◆ reset_vehicle_cache()

void map::reset_vehicle_cache ( )

Definition at line 250 of file map.cpp.

251{
254
255 // Cache all vehicles
256 const int zmin = zlevels ? -OVERMAP_DEPTH : abs_sub.z;
257 const int zmax = zlevels ? OVERMAP_HEIGHT : abs_sub.z;
258 for( int zlev = zmin; zlev <= zmax; zlev++ ) {
259 auto &ch = get_cache( zlev );
260 for( const auto &elem : ch.vehicle_list ) {
261 elem->adjust_zlevel( 0, tripoint_zero );
262 add_vehicle_to_cache( elem );
263 }
264 }
265}
void clear_vehicle_cache()
Definition: map.cpp:309

References abs_sub, add_vehicle_to_cache(), clear_vehicle_cache(), get_cache(), last_full_vehicle_list_dirty, OVERMAP_DEPTH, OVERMAP_HEIGHT, tripoint_zero, tripoint::z, and zlevels.

Referenced by veh_interact::complete_vehicle(), detach_vehicle(), editmap::draw_main_ui_overlay(), load(), loadn(), editmap::mapgen_preview(), editmap::mapgen_veh_destroy(), rotate(), shift(), and vehicle::use_bike_rack().

◆ restock_fruits()

void map::restock_fruits ( const tripoint p,
const time_duration time_since_last_actualize 
)
protected

Try to grow fruits on static plants (not planted by the player)

Parameters
pPlace to restock
time_since_last_actualizeTime since this function has been called the last time.

Definition at line 7087 of file map.cpp.

7088{
7089 const auto &ter = this->ter( p ).obj();
7090 if( !ter.has_flag( TFLAG_HARVESTED ) ) {
7091 return; // Already harvestable. Do nothing.
7092 }
7093 // Make it harvestable again if the last actualization was during a different season or year.
7094 const time_point last_touched = calendar::turn - time_since_last_actualize;
7095 if( season_of_year( calendar::turn ) != season_of_year( last_touched ) ||
7096 time_since_last_actualize >= calendar::season_length() ) {
7097 ter_set( p, ter.transforms_into );
7098 }
7099}
season_type season_of_year(const time_point &p)
Definition: calendar.cpp:547

References int_id< T >::obj(), calendar::season_length(), season_of_year(), ter(), ter_set(), TFLAG_HARVESTED, and calendar::turn.

Referenced by actualize(), and saven().

◆ rotate()

void map::rotate ( int  turns,
bool  setpos_safe = false 
)

Rotates this map, and all of its contents, by the specified multiple of 90 degrees.

Parameters
turnsHow many 90-degree turns to rotate the map.

Definition at line 5798 of file mapgen.cpp.

5799{
5800
5801 //Handle anything outside the 1-3 range gracefully; rotate(0) is a no-op.
5802 turns = turns % 4;
5803 if( turns == 0 ) {
5804 return;
5805 }
5806
5807 real_coords rc;
5808 const tripoint &abs_sub = get_abs_sub();
5809 rc.fromabs( point( abs_sub.x * SEEX, abs_sub.y * SEEY ) );
5810
5811 // TODO: This radius can be smaller - how small?
5812 const int radius = HALF_MAPSIZE + 3;
5813 // uses submap coordinates
5814 // TODO: fix point types
5815 const std::vector<shared_ptr_fast<npc>> npcs =
5817 for( const shared_ptr_fast<npc> &i : npcs ) {
5818 npc &np = *i;
5819 const tripoint sq = np.global_square_location();
5820 const point local_sq = getlocal( sq ).xy();
5821
5822 real_coords np_rc;
5823 np_rc.fromabs( sq.xy() );
5824 // Note: We are rotating the entire overmap square (2x2 of submaps)
5825 if( np_rc.om_pos != rc.om_pos || sq.z != abs_sub.z ) {
5826 continue;
5827 }
5828
5829 // OK, this is ugly: we remove the NPC from the whole map
5830 // Then we place it back from scratch
5831 // It could be rewritten to utilize the fact that rotation shouldn't cross overmaps
5832
5833 point old( np_rc.sub_pos );
5834 if( np_rc.om_sub.x % 2 != 0 ) {
5835 old.x += SEEX;
5836 }
5837 if( np_rc.om_sub.y % 2 != 0 ) {
5838 old.y += SEEY;
5839 }
5840
5841 const point new_pos = old .rotate( turns, { SEEX * 2, SEEY * 2 } );
5842 if( setpos_safe ) {
5843 // setpos can't be used during mapgen, but spawn_at_precise clips position
5844 // to be between 0-11,0-11 and teleports NPCs when used inside of update_mapgen
5845 // calls
5846 const tripoint new_global_sq = sq - local_sq + new_pos;
5847 np.setpos( get_map().getlocal( new_global_sq ) );
5848 } else {
5849 // OK, this is ugly: we remove the NPC from the whole map
5850 // Then we place it back from scratch
5851 // It could be rewritten to utilize the fact that rotation shouldn't cross overmaps
5853 np.spawn_at_precise( { abs_sub.xy() }, { new_pos, abs_sub.z } );
5855 }
5856 }
5857
5860
5861 // Move the submaps around.
5862 if( turns == 2 ) {
5865 } else {
5866 point p;
5867 submap tmp;
5868
5870
5871 for( int k = 0; k < 4; ++k ) {
5872 p = p.rotate( turns, { 2, 2 } );
5874 }
5875 }
5876
5877 // Then rotate them and recalculate vehicle positions.
5878 for( int j = 0; j < 2; ++j ) {
5879 for( int i = 0; i < 2; ++i ) {
5880 point p( i, j );
5881 auto sm = get_submap_at_grid( p );
5882
5883 sm->rotate( turns );
5884
5885 for( auto &veh : sm->vehicles ) {
5886 veh->sm_pos = tripoint( p, abs_sub.z );
5887 }
5888
5890 }
5891 }
5893
5894 // rotate zones
5896 mgr.rotate_zones( *this, turns );
5897}
shared_ptr_fast< npc > npc_ptr
Definition: basecamp.h:46
character_id getID() const
Definition: character.cpp:472
void clear_vehicle_list(int zlev)
Definition: map.cpp:327
void spawn_at_precise(const point &submap_offset, const tripoint &square)
As spawn_at, but also sets position within the submap.
Definition: npc.cpp:728
void setpos(const tripoint &pos) override
Note: this places NPC on a given position in CURRENT MAP coordinates.
Definition: npc.cpp:680
tripoint global_square_location() const override
Global position, expressed in map square coordinate system (the most detailed coordinate system),...
Definition: npc.cpp:738
std::vector< shared_ptr_fast< npc > > get_npcs_near(const tripoint_abs_sm &p, int radius)
Get all npcs in a area with given radius around given central point.
shared_ptr_fast< npc > remove_npc(const character_id &id)
Find npc by id and if found, erase it from the npc list and return it ( or return nullptr if not foun...
void rotate_zones(map &target_map, int turns)
Definition: clzones.cpp:1052
coords::coord_point< tripoint, coords::origin::abs, coords::sm > tripoint_abs_sm
Definition: coordinates.h:490
static constexpr int HALF_MAPSIZE
void swap(colony< element_type, element_allocator_type, element_skipfield_type > &a, colony< element_type, element_allocator_type, element_skipfield_type > &b) COLONY_NOEXCEPT_SWAP(element_allocator_type)
Swaps colony A's contents with that of colony B.
Definition: colony.h:3496
point rotate(int turns, const point &dim={ 1, 1 }) const
Rotate point clockwise.
Definition: point.h:89
point om_sub
Definition: coordinates.h:638
void fromabs(const point &abs)
Definition: coordinates.h:646
point om_pos
Definition: coordinates.h:637
point sub_pos
Definition: coordinates.h:635

References abs_sub, clear_vehicle_cache(), clear_vehicle_list(), real_coords::fromabs(), get_abs_sub(), zone_manager::get_manager(), get_map(), overmapbuffer::get_npcs_near(), get_submap_at_grid(), Character::getID(), getlocal(), npc::global_square_location(), HALF_MAPSIZE, overmapbuffer::insert_npc(), real_coords::om_pos, real_coords::om_sub, overmap_buffer, point_east, point_south, point_south_east, point_zero, overmapbuffer::remove_npc(), reset_vehicle_cache(), point::rotate(), zone_manager::rotate_zones(), SEEX, SEEY, npc::setpos(), coords::sm, npc::spawn_at_precise(), real_coords::sub_pos, cata::swap(), update_vehicle_list(), point::x, tripoint::x, tripoint::xy(), point::y, tripoint::y, and tripoint::z.

Referenced by draw_connections(), draw_lab(), draw_office_tower(), draw_triffid(), mapgen_function_json::generate(), mapgen_ants_curved(), mapgen_ants_straight(), mapgen_ants_tee(), mapgen_forest_trail_curved(), mapgen_forest_trail_straight(), mapgen_forest_trail_tee(), mapgen_highway(), mapgen_parking_lot(), editmap::mapgen_preview(), mapgen_railroad(), mapgen_railroad_bridge(), mapgen_river_curved(), mapgen_river_curved_not(), mapgen_river_straight(), mapgen_road(), mapgen_rotate(), mapgen_sewer_curved(), mapgen_sewer_straight(), mapgen_sewer_tee(), mapgen_subway(), and update_mapgen_function_json::update_map().

◆ rotten_item_spawn()

void map::rotten_item_spawn ( const item item,
const tripoint p 
)

Checks to see if the item that is rotting away generates a creature when it does.

Parameters
itemitem that is spawning creatures
pThe point on this map where the item is and creature will be

Definition at line 6961 of file map.cpp.

6962{
6963 if( g->critter_at( pnt ) != nullptr ) {
6964 return;
6965 }
6966 const auto &comest = item.get_comestible();
6967 mongroup_id mgroup = comest->rot_spawn;
6968 if( !mgroup ) {
6969 return;
6970 }
6971 const int chance = static_cast<int>( comest->rot_spawn_chance *
6972 get_option<float>( "CARRION_SPAWNRATE" ) );
6973 if( rng( 0, 100 ) < chance ) {
6975 add_spawn( spawn_details.name, 1, pnt, false );
6976 if( g->u.sees( pnt ) ) {
6977 if( item.is_seed() ) {
6978 add_msg( m_warning, _( "Something has crawled out of the %s plants!" ), item.get_plant_name() );
6979 } else {
6980 add_msg( m_warning, _( "Something has crawled out of the %s!" ), item.tname() );
6981 }
6982 }
6983 }
6984}
const cata::value_ptr< islot_comestible > & get_comestible() const
Definition: item.cpp:9940
std::string get_plant_name() const
The name of the plant as it appears in the various informational menus.
Definition: item.cpp:9609
bool is_seed() const
Whether this is actually a seed, the seed functions won't be of much use for non-seeds.
Definition: item.cpp:9590

References _, add_msg(), add_spawn(), g, item::get_comestible(), item::get_plant_name(), MonsterGroupManager::GetResultFromGroup(), item::is_seed(), m_warning, MonsterGroupResult::name, rng(), and item::tname().

Referenced by grow_plant(), and remove_rotten_items().

◆ route()

std::vector< tripoint > map::route ( const tripoint f,
const tripoint t,
const pathfinding_settings settings,
const std::set< tripoint > &  pre_closed = {{ }} 
) const

Calculate the best path using A*.

Parameters
fThe source location from which to path.
tThe destination to which to path.
settingsStructure describing pathfinding parameters.
pre_closedNever path through those points. They can still be the source or the destination.

Definition at line 194 of file pathfinding.cpp.

197{
198 /* TODO: If the origin or destination is out of bound, figure out the closest
199 * in-bounds point and go to that, then to the real origin/destination.
200 */
201 std::vector<tripoint> ret;
202
203 if( f == t || !inbounds( f ) ) {
204 return ret;
205 }
206
207 if( !inbounds( t ) ) {
208 tripoint clipped = t;
209 clip_to_bounds( clipped );
210 return route( f, clipped, settings, pre_closed );
211 }
212 // First, check for a simple straight line on flat ground
213 // Except when the line contains a pre-closed tile - we need to do regular pathing then
214 static const auto non_normal = PF_SLOW | PF_WALL | PF_VEHICLE | PF_TRAP | PF_SHARP;
215 if( f.z == t.z ) {
216 const auto line_path = line_to( f, t );
217 const auto &pf_cache = get_pathfinding_cache_ref( f.z );
218 // Check all points for any special case (including just hard terrain)
219 if( std::all_of( line_path.begin(), line_path.end(), [&pf_cache]( const tripoint & p ) {
220 return !( pf_cache.special[p.x][p.y] & non_normal );
221 } ) ) {
222 const std::set<tripoint> sorted_line( line_path.begin(), line_path.end() );
223
224 if( is_disjoint( sorted_line, pre_closed ) ) {
225 return line_path;
226 }
227 }
228 }
229
230 // If expected path length is greater than max distance, allow only line path, like above
231 if( rl_dist( f, t ) > settings.max_dist ) {
232 return ret;
233 }
234
235 int max_length = settings.max_length;
236 int bash = settings.bash_strength;
237 int climb_cost = settings.climb_cost;
238 bool doors = settings.allow_open_doors;
239 bool trapavoid = settings.avoid_traps;
240 bool roughavoid = settings.avoid_rough_terrain;
241 bool sharpavoid = settings.avoid_sharp;
242
243 const int pad = 16; // Should be much bigger - low value makes pathfinders dumb!
244 int minx = std::min( f.x, t.x ) - pad;
245 int miny = std::min( f.y, t.y ) - pad;
246 // TODO: Make this way bigger
247 int minz = std::min( f.z, t.z );
248 int maxx = std::max( f.x, t.x ) + pad;
249 int maxy = std::max( f.y, t.y ) + pad;
250 // Same TODO: as above
251 int maxz = std::max( f.z, t.z );
252 clip_to_bounds( minx, miny, minz );
253 clip_to_bounds( maxx, maxy, maxz );
254
255 pathfinder pf( point( minx, miny ), point( maxx, maxy ) );
256 // Make NPCs not want to path through player
257 // But don't make player pathing stop working
258 for( const auto &p : pre_closed ) {
259 if( p.x >= minx && p.x < maxx && p.y >= miny && p.y < maxy ) {
260 pf.close_point( p );
261 }
262 }
263
264 // Start and end must not be closed
265 pf.unclose_point( f );
266 pf.unclose_point( t );
267 pf.add_point( 0, 0, f, f );
268
269 bool done = false;
270
271 do {
272 auto cur = pf.get_next();
273
274 const int parent_index = flat_index( cur );
275 auto &layer = pf.get_layer( cur.z );
276 auto &cur_state = layer.state[parent_index];
277 if( cur_state == ASL_CLOSED ) {
278 continue;
279 }
280
281 if( layer.gscore[parent_index] > max_length ) {
282 // Shortest path would be too long, return empty vector
283 return std::vector<tripoint>();
284 }
285
286 if( cur == t ) {
287 done = true;
288 break;
289 }
290
291 cur_state = ASL_CLOSED;
292
293 const auto &pf_cache = get_pathfinding_cache_ref( cur.z );
294 const auto cur_special = pf_cache.special[cur.x][cur.y];
295
296 // 7 3 5
297 // 1 . 2
298 // 6 4 8
299 constexpr std::array<int, 8> x_offset{{ -1, 1, 0, 0, 1, -1, -1, 1 }};
300 constexpr std::array<int, 8> y_offset{{ 0, 0, -1, 1, -1, 1, -1, 1 }};
301 for( size_t i = 0; i < 8; i++ ) {
302 const tripoint p( cur.x + x_offset[i], cur.y + y_offset[i], cur.z );
303 const int index = flat_index( p );
304
305 // TODO: Remove this and instead have sentinels at the edges
306 if( p.x < minx || p.x >= maxx || p.y < miny || p.y >= maxy ) {
307 continue;
308 }
309
310 if( layer.state[index] == ASL_CLOSED ) {
311 continue;
312 }
313
314 // Penalize for diagonals or the path will look "unnatural"
315 int newg = layer.gscore[parent_index] + ( ( cur.x != p.x && cur.y != p.y ) ? 1 : 0 );
316
317 const auto p_special = pf_cache.special[p.x][p.y];
318 // TODO: De-uglify, de-huge-n
319 if( !( p_special & non_normal ) ) {
320 // Boring flat dirt - the most common case above the ground
321 newg += 2;
322 } else {
323 if( roughavoid ) {
324 layer.state[index] = ASL_CLOSED; // Close all rough terrain tiles
325 continue;
326 }
327
328 int part = -1;
329 const maptile &tile = maptile_at_internal( p );
330 const auto &terrain = tile.get_ter_t();
331 const auto &furniture = tile.get_furn_t();
332 const vehicle *veh = veh_at_internal( p, part );
333
334 const int cost = move_cost_internal( furniture, terrain, veh, part );
335 // Don't calculate bash rating unless we intend to actually use it
336 const int rating = ( bash == 0 || cost != 0 ) ? -1 :
337 bash_rating_internal( bash, furniture, terrain, false, veh, part );
338
339 if( cost == 0 && rating <= 0 && ( !doors || !terrain.open || !furniture.open ) && veh == nullptr &&
340 climb_cost <= 0 ) {
341 layer.state[index] = ASL_CLOSED; // Close it so that next time we won't try to calculate costs
342 continue;
343 }
344
345 newg += cost;
346 if( cost == 0 ) {
347 if( climb_cost > 0 && p_special & PF_CLIMBABLE ) {
348 // Climbing fences
349 newg += climb_cost;
350 } else if( doors && ( terrain.open || furniture.open ) &&
351 ( !terrain.has_flag( "OPENCLOSE_INSIDE" ) || !furniture.has_flag( "OPENCLOSE_INSIDE" ) ||
352 !is_outside( cur ) ) ) {
353 // Only try to open INSIDE doors from the inside
354 // To open and then move onto the tile
355 newg += 4;
356 } else if( veh != nullptr ) {
357 const auto vpobst = vpart_position( const_cast<vehicle &>( *veh ), part ).obstacle_at_part();
358 part = vpobst ? vpobst->part_index() : -1;
359 int dummy = -1;
360 if( doors && veh->part_flag( part, VPFLAG_OPENABLE ) &&
361 ( !veh->part_flag( part, "OPENCLOSE_INSIDE" ) ||
362 veh_at_internal( cur, dummy ) == veh ) ) {
363 // Handle car doors, but don't try to path through curtains
364 newg += 10; // One turn to open, 4 to move there
365 } else if( part >= 0 && bash > 0 ) {
366 // Car obstacle that isn't a door
367 // TODO: Account for armor
368 int hp = veh->cpart( part ).hp();
369 if( hp / 20 > bash ) {
370 // Threshold damage thing means we just can't bash this down
371 layer.state[index] = ASL_CLOSED;
372 continue;
373 } else if( hp / 10 > bash ) {
374 // Threshold damage thing means we will fail to deal damage pretty often
375 hp *= 2;
376 }
377
378 newg += 2 * hp / bash + 8 + 4;
379 } else if( part >= 0 ) {
380 if( !doors || !veh->part_flag( part, VPFLAG_OPENABLE ) ) {
381 // Won't be openable, don't try from other sides
382 layer.state[index] = ASL_CLOSED;
383 }
384
385 continue;
386 }
387 } else if( rating > 1 ) {
388 // Expected number of turns to bash it down, 1 turn to move there
389 // and 5 turns of penalty not to trash everything just because we can
390 newg += ( 20 / rating ) + 2 + 10;
391 } else if( rating == 1 ) {
392 // Desperate measures, avoid whenever possible
393 newg += 500;
394 } else {
395 // Unbashable and unopenable from here
396 if( !doors || !terrain.open || !furniture.open ) {
397 // Or anywhere else for that matter
398 layer.state[index] = ASL_CLOSED;
399 }
400
401 continue;
402 }
403 }
404
405 if( trapavoid && p_special & PF_TRAP ) {
406 const auto &ter_trp = terrain.trap.obj();
407 const auto &trp = ter_trp.is_benign() ? tile.get_trap_t() : ter_trp;
408 if( !trp.is_benign() ) {
409 // For now make them detect all traps
410 if( has_zlevels() && terrain.has_flag( TFLAG_NO_FLOOR ) ) {
411 // Special case - ledge in z-levels
412 // Warning: really expensive, needs a cache
413 if( valid_move( p, tripoint( p.xy(), p.z - 1 ), false, true ) ) {
414 tripoint below( p.xy(), p.z - 1 );
415 if( !has_flag( TFLAG_NO_FLOOR, below ) ) {
416 // Otherwise this would have been a huge fall
417 auto &layer = pf.get_layer( p.z - 1 );
418 // From cur, not p, because we won't be walking on air
419 pf.add_point( layer.gscore[parent_index] + 10,
420 layer.score[parent_index] + 10 + 2 * rl_dist( below, t ),
421 cur, below );
422 }
423
424 // Close p, because we won't be walking on it
425 layer.state[index] = ASL_CLOSED;
426 continue;
427 }
428 } else if( trapavoid ) {
429 // Otherwise it's walkable
430 newg += 500;
431 }
432 }
433 }
434
435 if( sharpavoid && p_special & PF_SHARP ) {
436 layer.state[index] = ASL_CLOSED; // Avoid sharp things
437 }
438
439 }
440
441 // If not visited, add as open
442 // If visited, add it only if we can do so with better score
443 if( layer.state[index] == ASL_NONE || newg < layer.gscore[index] ) {
444 pf.add_point( newg, newg + 2 * rl_dist( p, t ), cur, p );
445 }
446 }
447
448 if( !has_zlevels() || !( cur_special & PF_UPDOWN ) || !settings.allow_climb_stairs ) {
449 // The part below is only for z-level pathing
450 continue;
451 }
452
453 const maptile &parent_tile = maptile_at_internal( cur );
454 const auto &parent_terrain = parent_tile.get_ter_t();
455 if( settings.allow_climb_stairs && cur.z > minz && parent_terrain.has_flag( TFLAG_GOES_DOWN ) ) {
456 tripoint dest( cur.xy(), cur.z - 1 );
457 if( vertical_move_destination<TFLAG_GOES_UP>( *this, dest ) ) {
458 auto &layer = pf.get_layer( dest.z );
459 pf.add_point( layer.gscore[parent_index] + 2,
460 layer.score[parent_index] + 2 * rl_dist( dest, t ),
461 cur, dest );
462 }
463 }
464 if( settings.allow_climb_stairs && cur.z < maxz && parent_terrain.has_flag( TFLAG_GOES_UP ) ) {
465 tripoint dest( cur.xy(), cur.z + 1 );
466 if( vertical_move_destination<TFLAG_GOES_DOWN>( *this, dest ) ) {
467 auto &layer = pf.get_layer( dest.z );
468 pf.add_point( layer.gscore[parent_index] + 2,
469 layer.score[parent_index] + 2 * rl_dist( dest, t ),
470 cur, dest );
471 }
472 }
473 if( cur.z < maxz && parent_terrain.has_flag( TFLAG_RAMP ) &&
474 valid_move( cur, tripoint( cur.xy(), cur.z + 1 ), false, true ) ) {
475 auto &layer = pf.get_layer( cur.z + 1 );
476 for( size_t it = 0; it < 8; it++ ) {
477 const tripoint above( cur.x + x_offset[it], cur.y + y_offset[it], cur.z + 1 );
478 pf.add_point( layer.gscore[parent_index] + 4,
479 layer.score[parent_index] + 4 + 2 * rl_dist( above, t ),
480 cur, above );
481 }
482 }
483 if( cur.z < maxz && parent_terrain.has_flag( TFLAG_RAMP_UP ) &&
484 valid_move( cur, tripoint( cur.xy(), cur.z + 1 ), false, true, true ) ) {
485 auto &layer = pf.get_layer( cur.z + 1 );
486 for( size_t it = 0; it < 8; it++ ) {
487 const tripoint above( cur.x + x_offset[it], cur.y + y_offset[it], cur.z + 1 );
488 pf.add_point( layer.gscore[parent_index] + 4,
489 layer.score[parent_index] + 4 + 2 * rl_dist( above, t ),
490 cur, above );
491 }
492 }
493 if( cur.z > minz && parent_terrain.has_flag( TFLAG_RAMP_DOWN ) &&
494 valid_move( cur, tripoint( cur.xy(), cur.z - 1 ), false, true, true ) ) {
495 auto &layer = pf.get_layer( cur.z - 1 );
496 for( size_t it = 0; it < 8; it++ ) {
497 const tripoint below( cur.x + x_offset[it], cur.y + y_offset[it], cur.z - 1 );
498 pf.add_point( layer.gscore[parent_index] + 4,
499 layer.score[parent_index] + 4 + 2 * rl_dist( below, t ),
500 cur, below );
501 }
502 }
503
504 } while( !done && !pf.empty() );
505
506 if( done ) {
507 ret.reserve( rl_dist( f, t ) * 2 );
508 tripoint cur = t;
509 // Just to limit max distance, in case something weird happens
510 for( int fdist = max_length; fdist != 0; fdist-- ) {
511 const int cur_index = flat_index( cur );
512 const auto &layer = pf.get_layer( cur.z );
513 const tripoint &par = layer.parent[cur_index];
514 if( cur == f ) {
515 break;
516 }
517
518 ret.push_back( cur );
519 // Jumps are acceptable on 1 z-level changes
520 // This is because stairs teleport the player too
521 if( rl_dist( cur, par ) > 1 && std::abs( cur.z - par.z ) != 1 ) {
522 debugmsg( "Jump in our route! %d:%d:%d->%d:%d:%d",
523 cur.x, cur.y, cur.z, par.x, par.y, par.z );
524 return ret;
525 }
526
527 cur = par;
528 }
529
530 std::reverse( ret.begin(), ret.end() );
531 }
532
533 return ret;
534}
bool has_zlevels() const
Definition: map.h:1655
const pathfinding_cache & get_pathfinding_cache_ref(int zlev) const
Definition: map.cpp:8582
const vehicle_part & cpart(int part_num) const
Definition: vehicle.cpp:6908
bool part_flag(int p, const std::string &f) const
Definition: vehicle.cpp:2877
@ TFLAG_GOES_DOWN
Definition: mapdata.h:308
@ TFLAG_GOES_UP
Definition: mapdata.h:309
Definition: gates.h:28
Definition: overmap.h:50
bool is_disjoint(const Set1 &set1, const Set2 &set2)
constexpr int flat_index(const tripoint &p)
Definition: pathfinding.cpp:34
@ ASL_CLOSED
Definition: pathfinding.cpp:30
@ ASL_NONE
Definition: pathfinding.cpp:28
@ PF_VEHICLE
Definition: pathfinding.h:11
@ PF_WALL
Definition: pathfinding.h:10
@ PF_CLIMBABLE
Definition: pathfinding.h:15
@ PF_UPDOWN
Definition: pathfinding.h:14
@ PF_TRAP
Definition: pathfinding.h:13
@ PF_SHARP
Definition: pathfinding.h:16
@ PF_SLOW
Definition: pathfinding.h:9
const trap & get_trap_t() const
Definition: submap.h:293
@ VPFLAG_OPENABLE
Definition: veh_type.h:44

References pathfinding_settings::allow_climb_stairs, pathfinding_settings::allow_open_doors, ASL_CLOSED, ASL_NONE, pathfinding_settings::avoid_rough_terrain, pathfinding_settings::avoid_sharp, pathfinding_settings::avoid_traps, bash(), bash_rating_internal(), pathfinding_settings::bash_strength, pathfinding_settings::climb_cost, clip_to_bounds(), vehicle::cpart(), debugmsg, detail::digits::done, flat_index(), furniture, maptile::get_furn_t(), get_pathfinding_cache_ref(), maptile::get_ter_t(), maptile::get_trap_t(), has_flag(), has_zlevels(), vehicle_part::hp(), inbounds(), is_disjoint(), is_outside(), line_to(), maptile_at_internal(), pathfinding_settings::max_dist, pathfinding_settings::max_length, move_cost_internal(), vpart_position::obstacle_at_part(), vehicle::part_flag(), PF_CLIMBABLE, PF_SHARP, PF_SLOW, PF_TRAP, PF_UPDOWN, PF_VEHICLE, PF_WALL, cata::hash64_detail::ret, rl_dist(), route(), terrain, TFLAG_GOES_DOWN, TFLAG_GOES_UP, TFLAG_NO_FLOOR, TFLAG_RAMP, TFLAG_RAMP_DOWN, TFLAG_RAMP_UP, valid_move(), veh_at_internal(), VPFLAG_OPENABLE, tripoint::x, tripoint::xy(), tripoint::y, and tripoint::z.

Referenced by activity_on_turn_move_loot(), add_item_or_charges(), npc::go_to_omt_destination(), game::handle_action(), game::list_items(), game::look_around(), perform_zone_activity_turn(), route(), route_adjacent(), activity_handlers::travel_do_turn(), game::try_get_left_click_action(), and npc::update_path().

◆ save()

void map::save ( )

Add currently loaded submaps (in grid) to the mapbuffer.

They will than be stored by that class and can be loaded from that class. This can be called several times, the mapbuffer takes care of adding the same submap several times. It should only be called after the map has been loaded. Submaps that have been loaded from the mapbuffer (and not generated) are already stored in the mapbuffer. TODO: determine if this is really needed? Submaps are already in the mapbuffer if they have been loaded from disc and the are added by map::generate, too. So when do they not appear in the mapbuffer?

Definition at line 6479 of file map.cpp.

6480{
6481 for( int gridx = 0; gridx < my_MAPSIZE; gridx++ ) {
6482 for( int gridy = 0; gridy < my_MAPSIZE; gridy++ ) {
6483 if( zlevels ) {
6484 for( int gridz = -OVERMAP_DEPTH; gridz <= OVERMAP_HEIGHT; gridz++ ) {
6485 saven( tripoint( gridx, gridy, gridz ) );
6486 }
6487 } else {
6488 saven( tripoint( gridx, gridy, abs_sub.z ) );
6489 }
6490 }
6491 }
6492}

References abs_sub, my_MAPSIZE, OVERMAP_DEPTH, OVERMAP_HEIGHT, saven(), tripoint::z, and zlevels.

Referenced by start_location::add_map_extra(), add_monsters(), start_location::burn(), talk_function::buy_100_logs(), talk_function::buy_10_logs(), create_lab_consoles(), construct::done_digormine_stair(), construct::done_mine_upstair(), farm_action(), talk_function::field_build_1(), talk_function::field_build_2(), talk_function::field_harvest(), talk_function::field_plant(), defense_game::init_map(), mission_start::kill_horde_master(), talk_function::loot_building(), om_cutdown_trees(), om_harvest_furn(), om_harvest_itm(), om_harvest_ter(), om_set_hide_site(), mission_start::place_deposit_box(), mission_start::place_dog(), mission_start::place_npc_software(), mission_start::place_priest_diary(), basecamp::place_results(), game::place_vehicle_nearby(), mission_start::place_zombie_mom(), start_location::prepare_map(), mission_start::ranch_nurse_1(), mission_start::ranch_nurse_2(), mission_start::ranch_nurse_3(), mission_start::ranch_nurse_4(), mission_start::ranch_nurse_5(), mission_start::ranch_nurse_6(), mission_start::ranch_nurse_7(), mission_start::ranch_nurse_8(), mission_start::ranch_nurse_9(), mission_start::ranch_scavenger_1(), mission_start::ranch_scavenger_2(), mission_start::ranch_scavenger_3(), mission_start::reveal_lab_train_depot(), game::save_maps(), and debug_menu::spawn_nested_mapgen().

◆ saven()

void map::saven ( const tripoint grid)
protected

Definition at line 6795 of file map.cpp.

6796{
6797 dbg( DL::Debug ) << "map::saven( world=" << abs_sub << ", grid=" << grid << " )";
6798 const int gridn = get_nonant( grid );
6799 submap *submap_to_save = getsubmap( gridn );
6800 if( submap_to_save == nullptr || submap_to_save->get_ter( point_zero ) == t_null ) {
6801 // This is a serious error and should be signaled as soon as possible
6802 debugmsg( "map::saven grid (%s) %s!", grid.to_string(),
6803 submap_to_save == nullptr ? "null" : "uninitialized" );
6804 return;
6805 }
6806
6807 const tripoint abs = abs_sub.xy() + grid;
6808
6809 if( !zlevels && grid.z != abs_sub.z ) {
6810 debugmsg( "Tried to save submap (%d,%d,%d) as (%d,%d,%d), which isn't supported in non-z-level builds",
6811 abs.x, abs.y, abs_sub.z, abs.x, abs.y, grid.z );
6812 }
6813
6814 dbg( DL::Debug ) << "map::saven abs: " << abs << " gridn: " << gridn;
6815
6816 // An edge case: restock_fruits relies on last_touched, so we must call it before save
6817 if( season_of_year( calendar::turn ) != season_of_year( submap_to_save->last_touched ) ) {
6818 const time_duration time_since_last_actualize = calendar::turn - submap_to_save->last_touched;
6819 for( int x = 0; x < SEEX; x++ ) {
6820 for( int y = 0; y < SEEY; y++ ) {
6821 const tripoint pnt = sm_to_ms_copy( grid ) + point( x, y );
6822 restock_fruits( pnt, time_since_last_actualize );
6823 }
6824 }
6825 }
6826
6827 submap_to_save->last_touched = calendar::turn;
6828 MAPBUFFER.add_submap( abs, submap_to_save );
6829}
bool add_submap(const tripoint &p, std::unique_ptr< submap > &sm)
Add a new submap to the buffer.
Definition: mapbuffer.cpp:68
@ Debug
Debug information (default: disabled).

References abs_sub, mapbuffer::add_submap(), dbg, Debug, debugmsg, get_nonant(), submap::get_ter(), getsubmap(), grid, submap::last_touched, MAPBUFFER, point_zero, restock_fruits(), season_of_year(), SEEX, SEEY, sm_to_ms_copy(), t_null, calendar::turn, tripoint::xy(), tripoint::z, and zlevels.

Referenced by generate(), and save().

◆ scent_blockers()

void map::scent_blockers ( std::array< std::array< bool, MAPSIZE_X >, MAPSIZE_Y > &  blocks_scent,
std::array< std::array< bool, MAPSIZE_X >, MAPSIZE_Y > &  reduces_scent,
const point min,
const point max 
)

Build the map of scent-resistant tiles.

Should be way faster than if done in game.cpp using public map functions.

Definition at line 8358 of file map.cpp.

8361{
8362 auto reduce = TFLAG_REDUCE_SCENT;
8363 auto block = TFLAG_NO_SCENT;
8364 auto fill_values = [&]( const tripoint & gp, const submap * sm, const point & lp ) {
8365 // We need to generate the x/y coordinates, because we can't get them "for free"
8366 const point p = lp + sm_to_ms_copy( gp.xy() );
8367 if( sm->get_ter( lp ).obj().has_flag( block ) ) {
8368 blocks_scent[p.x][p.y] = true;
8369 reduces_scent[p.x][p.y] = false;
8370 } else if( sm->get_ter( lp ).obj().has_flag( reduce ) ||
8371 sm->get_furn( lp ).obj().has_flag( reduce ) ) {
8372 blocks_scent[p.x][p.y] = false;
8373 reduces_scent[p.x][p.y] = true;
8374 } else {
8375 blocks_scent[p.x][p.y] = false;
8376 reduces_scent[p.x][p.y] = false;
8377 }
8378
8379 return ITER_CONTINUE;
8380 };
8381
8382 function_over( tripoint( min, abs_sub.z ), tripoint( max, abs_sub.z ), fill_values );
8383
8384 const inclusive_rectangle<point> local_bounds( min, max );
8385
8386 // Now vehicles
8387
8388 auto vehs = get_vehicles();
8389 for( auto &wrapped_veh : vehs ) {
8390 vehicle &veh = *( wrapped_veh.v );
8391 for( const vpart_reference &vp : veh.get_any_parts( VPFLAG_OBSTACLE ) ) {
8392 const tripoint part_pos = vp.pos();
8393 if( local_bounds.contains( part_pos.xy() ) ) {
8394 reduces_scent[part_pos.x][part_pos.y] = true;
8395 }
8396 }
8397
8398 // Doors, but only the closed ones
8399 for( const vpart_reference &vp : veh.get_any_parts( VPFLAG_OPENABLE ) ) {
8400 if( vp.part().open ) {
8401 continue;
8402 }
8403
8404 const tripoint part_pos = vp.pos();
8405 if( local_bounds.contains( part_pos.xy() ) ) {
8406 reduces_scent[part_pos.x][part_pos.y] = true;
8407 }
8408 }
8409 }
8410}
void function_over(const tripoint &start, const tripoint &end, Functor fun) const
Runs a functor over given submaps over submaps in the area, getting next submap only when the current...
Definition: map.cpp:8304
@ TFLAG_REDUCE_SCENT
Definition: mapdata.h:278
@ TFLAG_NO_SCENT
Definition: mapdata.h:284
@ VPFLAG_OBSTACLE
Definition: veh_type.h:42

References abs_sub, inclusive_rectangle< Point, >::contains(), function_over(), vehicle::get_any_parts(), get_vehicles(), ITER_CONTINUE, coords::sm, sm_to_ms_copy(), TFLAG_NO_SCENT, TFLAG_REDUCE_SCENT, VPFLAG_OBSTACLE, VPFLAG_OPENABLE, point::x, tripoint::x, tripoint::xy(), point::y, tripoint::y, and tripoint::z.

Referenced by scent_map::update().

◆ sees() [1/2]

bool map::sees ( const tripoint F,
const tripoint T,
int  range 
) const

Returns whether F sees T with a view range of range.

Definition at line 6100 of file map.cpp.

6101{
6102 int dummy = 0;
6103 return sees( F, T, range, dummy );
6104}

References sees().

Referenced by apply_ammo_effects(), find_clear_path(), explosion_handler::explosion_funcs::flashbang(), get_heat_radiation(), projectile_attack(), Creature::sees(), sees(), Character::sees_with_infrared(), shake_vehicle(), shoot(), spawn_monsters_submap_group(), and vehicle_selector::vehicle_selector().

◆ sees() [2/2]

bool map::sees ( const tripoint F,
const tripoint T,
int  range,
int &  bresenham_slope 
) const
private

Don't expose the slope adjust outside map functions.

This one is internal-only, we don't want to expose the slope tweaking ickiness outside the map class.

Parameters
FThing doing the seeing
TThing being seen
rangeVision range of F
bresenham_slopeIndicates the start offset of Bresenham line used to connect the two points, and may subsequently be used to form a path between them. Set to zero if the function returns false.

Definition at line 6109 of file map.cpp.

6111{
6112 if( ( range >= 0 && range < rl_dist( F, T ) ) ||
6113 !inbounds( T ) ) {
6114 bresenham_slope = 0;
6115 return false; // Out of range!
6116 }
6117 // Cannonicalize the order of the tripoints so the cache is reflexive.
6118 const tripoint &min = F < T ? F : T;
6119 const tripoint &max = !( F < T ) ? F : T;
6120 // A little gross, just pack the values into a point.
6121 const point key(
6122 min.x << 16 | min.y << 8 | ( min.z + OVERMAP_DEPTH ),
6123 max.x << 16 | max.y << 8 | ( max.z + OVERMAP_DEPTH )
6124 );
6125 char cached = skew_vision_cache.get( key, -1 );
6126 if( cached >= 0 ) {
6127 return cached > 0;
6128 }
6129
6130 bool visible = true;
6131
6132 // Ugly `if` for now
6133 if( !fov_3d || F.z == T.z ) {
6134 bresenham( F.xy(), T.xy(), bresenham_slope,
6135 [this, &visible, &T]( const point & new_point ) {
6136 // Exit before checking the last square, it's still visible even if opaque.
6137 if( new_point.x == T.x && new_point.y == T.y ) {
6138 return false;
6139 }
6140 if( !this->is_transparent( tripoint( new_point, T.z ) ) ) {
6141 visible = false;
6142 return false;
6143 }
6144 return true;
6145 } );
6146 skew_vision_cache.insert( 100000, key, visible ? 1 : 0 );
6147 return visible;
6148 }
6149
6150 tripoint last_point = F;
6151 bresenham( F, T, bresenham_slope, 0,
6152 [this, &visible, &T, &last_point]( const tripoint & new_point ) {
6153 // Exit before checking the last square if it's not a vertical transition,
6154 // it's still visible even if opaque.
6155 if( new_point == T && last_point.z == T.z ) {
6156 return false;
6157 }
6158
6159 // TODO: Allow transparent floors (and cache them!)
6160 if( new_point.z == last_point.z ) {
6161 if( !this->is_transparent( new_point ) ) {
6162 visible = false;
6163 return false;
6164 }
6165 } else {
6166 const int max_z = std::max( new_point.z, last_point.z );
6167 if( ( has_floor_or_support( {new_point.xy(), max_z} ) ||
6168 !is_transparent( {new_point.xy(), last_point.z} ) ) &&
6169 ( has_floor_or_support( {last_point.xy(), max_z} ) ||
6170 !is_transparent( {last_point.xy(), new_point.z} ) ) ) {
6171 visible = false;
6172 return false;
6173 }
6174 }
6175
6176 last_point = new_point;
6177 return true;
6178 } );
6179 skew_vision_cache.insert( 100000, key, visible ? 1 : 0 );
6180 return visible;
6181}

References bresenham(), fov_3d, inbounds(), OVERMAP_DEPTH, rl_dist(), skew_vision_cache, tripoint::x, tripoint::xy(), tripoint::y, and tripoint::z.

◆ sees_some_items() [1/2]

bool map::sees_some_items ( const tripoint p,
const Creature who 
) const

Check if creature can see some items at p.

Includes:

  • check for items at this location (has_items(p))
  • check for SEALED flag (sealed furniture/terrain makes items not visible under any circumstances).
  • check for CONTAINER flag (makes items only visible when the creature is at p or at an adjacent square).

Definition at line 4715 of file map.cpp.

4716{
4717 // Can only see items if there are any items.
4718 return has_items( p ) && could_see_items( p, who.pos() );
4719}

References could_see_items(), has_items(), and Creature::pos().

Referenced by game::butcher(), editmap::draw_main_ui_overlay(), draw_maptile(), npc::find_corpse_to_pulp(), npc::find_item(), game::find_nearby_items(), game::print_items_info(), and npc::see_item_say_smth().

◆ sees_some_items() [2/2]

bool map::sees_some_items ( const tripoint p,
const tripoint from 
) const

Definition at line 4721 of file map.cpp.

4722{
4723 return has_items( p ) && could_see_items( p, from );
4724}

References could_see_items(), and has_items().

◆ set() [1/2]

void map::set ( const point p,
const ter_id new_terrain,
const furn_id new_furniture 
)
inline

Definition at line 808 of file map.h.

808 {
809 furn_set( p, new_furniture );
810 ter_set( p, new_terrain );
811 }

References furn_set(), and ter_set().

◆ set() [2/2]

void map::set ( const tripoint p,
const ter_id new_terrain,
const furn_id new_furniture 
)

Definition at line 1314 of file map.cpp.

1315{
1316 furn_set( p, new_furniture );
1317 ter_set( p, new_terrain );
1318}

References furn_set(), and ter_set().

Referenced by farm_action(), talk_function::field_plant(), mapgen_function_json_base::formatted_set_incredibly_simple(), and activity_handlers::plant_seed_finish().

◆ set_abs_sub()

void map::set_abs_sub ( const tripoint p)
protected

Sets abs_sub, see there.

Uses the same coordinate system as abs_sub.

Definition at line 8084 of file map.cpp.

8085{
8086 abs_sub = p;
8087}

References abs_sub.

Referenced by fake_map::fake_map(), generate(), load(), shift(), and vertical_shift().

◆ set_field_age()

time_duration map::set_field_age ( const tripoint p,
const field_type_id type,
const time_duration age,
bool  isoffset = false 
)

Set age of field entry at point.

Parameters
pLocation of field
typeID of field
ageNew age of specified field
isoffsetIf true, the given age value is added to the existing value, if false, the existing age is ignored and overridden.
Returns
resulting age or -1_turns if not present (does not create a new field).

Definition at line 5317 of file map.cpp.

5319{
5320 if( field_entry *const field_ptr = get_field( p, type ) ) {
5321 return field_ptr->set_field_age( ( isoffset ? field_ptr->get_field_age() : 0_turns ) + age );
5322 }
5323 return -1_turns;
5324}

References get_field(), and type.

Referenced by game::grabbed_furn_move(), mod_field_age(), and game::walk_move().

◆ set_field_intensity()

int map::set_field_intensity ( const tripoint p,
const field_type_id type,
int  new_intensity,
bool  isoffset = false 
)

Set intensity of field entry at point, creating if not present, removing if intensity becomes 0.

Parameters
pLocation of field
typeID of field
new_intensityNew intensity of field
isoffsetIf true, the given new_intensity value is added to the existing value, if false, the existing intensity is ignored and overridden.
Returns
resulting intensity, or 0 for not present (either removed or not created at all).

Definition at line 5330 of file map.cpp.

5333{
5334 field_entry *field_ptr = get_field( p, type );
5335 if( field_ptr != nullptr ) {
5336 int adj = ( isoffset ? field_ptr->get_field_intensity() : 0 ) + new_intensity;
5337 if( adj > 0 ) {
5338 field_ptr->set_field_intensity( adj );
5339 return adj;
5340 } else {
5341 remove_field( p, type );
5342 return 0;
5343 }
5344 } else if( 0 + new_intensity > 0 ) {
5345 return add_field( p, type, new_intensity ) ? new_intensity : 0;
5346 }
5347
5348 return 0;
5349}

References add_field(), get_field(), field_entry::get_field_intensity(), remove_field(), field_entry::set_field_intensity(), and type.

Referenced by editmap::edit_fld(), game::grabbed_furn_move(), mod_field_intensity(), and game::walk_move().

◆ set_floor_cache_dirty()

void map::set_floor_cache_dirty ( const int  zlev)
inline

◆ set_graffiti()

void map::set_graffiti ( const tripoint p,
const std::string &  contents 
)

Definition at line 7660 of file map.cpp.

7661{
7662 if( !inbounds( p ) ) {
7663 return;
7664 }
7665 point l;
7666 submap *const current_submap = get_submap_at( p, l );
7667 current_submap->set_graffiti( l, contents );
7668}
void set_graffiti(const point &p, const std::string &new_graffiti)
Definition: submap.cpp:97

References get_submap_at(), inbounds(), and submap::set_graffiti().

Referenced by jmapgen_graffiti::apply().

◆ set_memory_seen_cache_dirty()

void map::set_memory_seen_cache_dirty ( const tripoint p)
inline

Definition at line 451 of file map.h.

451 {
452 const int offset = p.x + p.y * MAPSIZE_Y;
453 if( offset >= 0 && offset < MAPSIZE_X * MAPSIZE_Y ) {
454 get_cache( p.z ).map_memory_seen_cache.reset( offset );
455 }
456 }

References get_cache(), level_cache::map_memory_seen_cache, MAPSIZE_X, MAPSIZE_Y, tripoint::x, tripoint::y, and tripoint::z.

Referenced by furn_set(), vehicle::stop(), and ter_set().

◆ set_outside_cache_dirty()

void map::set_outside_cache_dirty ( const int  zlev)
inline

Definition at line 430 of file map.h.

430 {
431 if( inbounds_z( zlev ) ) {
432 get_cache( zlev ).outside_cache_dirty = true;
433 }
434 }

References get_cache(), inbounds_z(), and level_cache::outside_cache_dirty.

Referenced by draw_fill_background(), furn_set(), loadn(), editmap::mapgen_preview(), on_vehicle_moved(), ter_set(), and game::vertical_shift().

◆ set_pathfinding_cache_dirty()

void map::set_pathfinding_cache_dirty ( int  zlev)

◆ set_radiation() [1/2]

void map::set_radiation ( const point p,
const int  value 
)
inline

Definition at line 1184 of file map.h.

1184 {
1185 set_radiation( tripoint( p, abs_sub.z ), value );
1186 }

References abs_sub, set_radiation(), and tripoint::z.

◆ set_radiation() [2/2]

void map::set_radiation ( const tripoint p,
int  value 
)

Definition at line 4025 of file map.cpp.

4026{
4027 if( !inbounds( p ) ) {
4028 return;
4029 }
4030
4031 point l;
4032 submap *const current_submap = get_submap_at( p, l );
4033
4034 current_submap->set_radiation( l, value );
4035}

References get_submap_at(), inbounds(), and submap::set_radiation().

Referenced by jmapgen_setmap::apply(), create_anomaly(), draw_lab(), mapgen_crater(), mapgen_null(), and set_radiation().

◆ set_seen_cache_dirty() [1/2]

void map::set_seen_cache_dirty ( const int  zlevel)
inline

Definition at line 423 of file map.h.

423 {
424 if( inbounds_z( zlevel ) ) {
425 level_cache &cache = get_cache( zlevel );
426 cache.seen_cache_dirty = true;
427 }
428 }

References get_cache(), inbounds_z(), and level_cache::seen_cache_dirty.

◆ set_seen_cache_dirty() [2/2]

void map::set_seen_cache_dirty ( const tripoint  change_location)
inline

Definition at line 409 of file map.h.

409 {
410 if( inbounds( change_location ) ) {
411 level_cache &cache = get_cache( change_location.z );
412 if( cache.seen_cache_dirty ) {
413 return;
414 }
415 if( cache.seen_cache[change_location.x][change_location.y] != 0.0 ||
416 cache.camera_cache[change_location.x][change_location.y] != 0.0 ) {
417 cache.seen_cache_dirty = true;
418 }
419 }
420 }

References level_cache::camera_cache, get_cache(), inbounds(), level_cache::seen_cache, level_cache::seen_cache_dirty, tripoint::x, tripoint::y, and tripoint::z.

Referenced by add_field(), draw_fill_background(), furn_set(), loadn(), trapfunc::map_regen(), vehicle::merge_rackable_vehicle(), vehicle::open_or_close(), process_fields_in_submap(), remove_field(), avatar::set_movement_mode(), DefaultRemovePartHandler::set_transparency_cache_dirty(), vehicle::split_vehicles(), ter_set(), and weather_manager::update_weather().

◆ set_signage()

void map::set_signage ( const tripoint p,
const std::string &  message 
) const

Definition at line 3990 of file map.cpp.

3991{
3992 if( !inbounds( p ) ) {
3993 return;
3994 }
3995
3996 point l;
3997 submap *const current_submap = get_submap_at( p, l );
3998
3999 current_submap->set_signage( l, message );
4000}
void set_signage(const point &p, const std::string &s)
Definition: submap.cpp:137
std::string message
Definition: mapgen.cpp:403

References get_submap_at(), inbounds(), mapgen_defer::message, and submap::set_signage().

Referenced by jmapgen_sign::apply(), MapExtras::mx_grave(), MapExtras::mx_minefield(), and iexamine::sign().

◆ set_suspension_cache_dirty()

void map::set_suspension_cache_dirty ( const int  zlev)
inline

Definition at line 442 of file map.h.

442 {
443 if( inbounds_z( zlev ) ) {
444 get_cache( zlev ).suspension_cache_dirty = true;
445 }
446 }

References get_cache(), inbounds_z(), and level_cache::suspension_cache_dirty.

Referenced by loadn(), editmap::mapgen_preview(), and ter_set().

◆ set_temperature() [1/2]

void map::set_temperature ( const point p,
int  new_temperature 
)
inline

Definition at line 1201 of file map.h.

1201 {
1202 set_temperature( tripoint( p, abs_sub.z ), new_temperature );
1203 }

References abs_sub, set_temperature(), and tripoint::z.

◆ set_temperature() [2/2]

void map::set_temperature ( const tripoint p,
int  temperature 
)

Definition at line 4059 of file map.cpp.

4060{
4061 if( !inbounds( p ) ) {
4062 return;
4063 }
4064
4065 get_submap_at( p )->set_temperature( new_temperature );
4066}
void set_temperature(int new_temperature)
Definition: submap.h:198

References get_submap_at(), inbounds(), and submap::set_temperature().

Referenced by draw_lab(), and set_temperature().

◆ set_transparency_cache_dirty() [1/2]

void map::set_transparency_cache_dirty ( const int  zlev)
inline

◆ set_transparency_cache_dirty() [2/2]

void map::set_transparency_cache_dirty ( const tripoint p)
inline

Definition at line 402 of file map.h.

402 {
403 if( inbounds( p ) ) {
404 const tripoint smp = ms_to_sm_copy( p );
405 get_cache( smp.z ).transparency_cache_dirty.set( smp.x * MAPSIZE + smp.y );
406 }
407 }

References get_cache(), inbounds(), MAPSIZE, ms_to_sm_copy(), level_cache::transparency_cache_dirty, tripoint::x, tripoint::y, and tripoint::z.

◆ setsubmap()

void map::setsubmap ( size_t  grididx,
submap smap 
)
protected

Set the submap pointer in grid at the give index.

This is the inverse of getsubmap, any existing pointer is overwritten. The index must be valid. The given submap pointer must not be null.

Definition at line 8103 of file map.cpp.

8104{
8105 if( grididx >= grid.size() ) {
8106 debugmsg( "Tried to access invalid grid index %d", grididx );
8107 return;
8108 } else if( smap == nullptr ) {
8109 debugmsg( "Tried to set NULL submap pointer at index %d", grididx );
8110 return;
8111 }
8112 grid[grididx] = smap;
8113}

References debugmsg, and grid.

Referenced by copy_grid(), fake_map::fake_map(), generate(), and loadn().

◆ shake_vehicle()

units::angle map::shake_vehicle ( vehicle veh,
int  velocity_before,
units::angle  direction 
)
Strength reduces chance of being thrown from your seat when not wearing a seatbelt Strength reduces chance of being thrown from your seat when not wearing a seatbelt Dexterity reduces chance of losing control of vehicle when shaken Driving reduces chance of losing control of vehicle when shaken Strength reduces distance thrown from seat in a vehicle impact

Definition at line 1631 of file vehicle_move.cpp.

1633{
1634 const int d_vel = std::abs( veh.velocity - velocity_before ) / 100;
1635
1636 std::vector<rider_data> riders = veh.get_riders();
1637
1638 units::angle coll_turn = 0_degrees;
1639 for( const rider_data &r : riders ) {
1640 const int ps = r.prt;
1641 Creature *rider = r.psg;
1642 if( rider == nullptr ) {
1643 debugmsg( "throw passenger: empty passenger at part %d", ps );
1644 continue;
1645 }
1646
1647 const tripoint part_pos = veh.global_part_pos3( ps );
1648 if( rider->pos() != part_pos ) {
1649 debugmsg( "throw passenger: passenger at %d,%d,%d, part at %d,%d,%d",
1650 rider->posx(), rider->posy(), rider->posz(),
1651 part_pos.x, part_pos.y, part_pos.z );
1653 continue;
1654 }
1655
1656 player *psg = dynamic_cast<player *>( rider );
1657 monster *pet = dynamic_cast<monster *>( rider );
1658
1659 bool throw_from_seat = false;
1660 int move_resist = 1;
1661 if( psg ) {
1662 ///\EFFECT_STR reduces chance of being thrown from your seat when not wearing a seatbelt
1663 move_resist = psg->str_cur * 150 + 500;
1664 } else {
1665 int pet_resist = 0;
1666 if( pet != nullptr ) {
1667 pet_resist = static_cast<int>( to_kilogram( pet->get_weight() ) * 200 );
1668 }
1669 move_resist = std::max( 100, pet_resist );
1670 }
1671 if( veh.part_with_feature( ps, VPFLAG_SEATBELT, true ) == -1 ) {
1672 ///\EFFECT_STR reduces chance of being thrown from your seat when not wearing a seatbelt
1673 throw_from_seat = d_vel * rng( 80, 120 ) > move_resist;
1674 }
1675
1676 // Damage passengers if d_vel is too high
1677 if( !throw_from_seat && ( 10 * d_vel ) > 6 * rng( 50, 100 ) ) {
1678 const int dmg = d_vel * rng( 70, 100 ) / 400;
1679 if( psg ) {
1680 psg->hurtall( dmg, nullptr );
1682 _( "You take %d damage by the power of the impact!" ),
1683 _( "<npcname> takes %d damage by the power of the "
1684 "impact!" ), dmg );
1685 } else {
1686 pet->apply_damage( nullptr, bodypart_id( "torso" ), dmg );
1687 }
1688 }
1689
1690 if( psg && veh.player_in_control( *psg ) ) {
1691 const int lose_ctrl_roll = rng( 0, d_vel );
1692 ///\EFFECT_DEX reduces chance of losing control of vehicle when shaken
1693
1694 ///\EFFECT_DRIVING reduces chance of losing control of vehicle when shaken
1695 if( lose_ctrl_roll > psg->dex_cur * 2 + psg->get_skill_level( skill_driving ) * 3 ) {
1697 _( "You lose control of the %s." ),
1698 _( "<npcname> loses control of the %s." ), veh.name );
1699 int turn_amount = rng( 1, 3 ) * std::sqrt( std::abs( veh.velocity ) ) / 30;
1700 if( turn_amount < 1 ) {
1701 turn_amount = 1;
1702 }
1703 units::angle turn_angle = std::min( turn_amount * 15_degrees, 120_degrees );
1704 coll_turn = one_in( 2 ) ? turn_angle : -turn_angle;
1705 }
1706 }
1707
1708 if( throw_from_seat ) {
1709 if( psg ) {
1711 _( "You are hurled from the %s's seat by "
1712 "the power of the impact!" ),
1713 _( "<npcname> is hurled from the %s's seat by "
1714 "the power of the impact!" ), veh.name );
1715 unboard_vehicle( part_pos );
1716 } else if( get_player_character().sees( part_pos ) ) {
1717 add_msg( m_bad, _( "The %s is hurled from %s's by the power of the impact!" ),
1718 pet->disp_name(), veh.name );
1719 }
1720 ///\EFFECT_STR reduces distance thrown from seat in a vehicle impact
1721 g->fling_creature( rider, direction + rng_float( -30_degrees, 30_degrees ),
1722 std::max( 10, d_vel - move_resist / 100 ) );
1723 }
1724 }
1725
1726 return coll_turn;
1727}
int dex_cur
Definition: character.h:305
int get_skill_level(const skill_id &ident) const
Definition: character.cpp:3354
units::mass get_weight() const override
Definition: monster.cpp:2673
std::string disp_name(bool possessive=false, bool capitalize_first=false) const override
Definition: monster.cpp:536
int part_with_feature(int p, const std::string &f, bool unbroken) const
Definition: vehicle.cpp:2520
@ VPFLAG_SEATBELT
Definition: veh_type.h:45
static const skill_id skill_driving("driving")

References _, add_msg(), player::add_msg_player_or_npc(), monster::apply_damage(), debugmsg, Character::dex_cur, monster::disp_name(), g, get_player_character(), vehicle::get_riders(), Character::get_skill_level(), monster::get_weight(), vehicle::global_part_pos3(), Character::hurtall(), m_bad, m_warning, vehicle::name, one_in(), vehicle::part(), vehicle::part_with_feature(), vehicle_part::passenger_flag, vehicle::player_in_control(), Creature::pos(), Creature::posx(), Creature::posy(), Creature::posz(), vehicle_part::remove_flag(), rng(), rng_float(), sees(), skill_driving, Character::str_cur, units::to_kilogram(), unboard_vehicle(), vehicle::velocity, VPFLAG_SEATBELT, tripoint::x, tripoint::y, and tripoint::z.

Referenced by move_vehicle().

◆ shift()

void map::shift ( const point s)

Shift the map along the vector s.

This is like loading the map with coordinates derived from the current position of the map (abs_sub) plus the shift vector. Note: the map must have been loaded before this can be called.

Definition at line 6648 of file map.cpp.

6649{
6650 // Special case of 0-shift; refresh the map
6651 if( sp == point_zero ) {
6652 return; // Skip this?
6653 }
6654
6655 if( std::abs( sp.x ) > 1 || std::abs( sp.y ) > 1 ) {
6656 debugmsg( "map::shift called with a shift of more than one submap" );
6657 }
6658
6659 const tripoint abs = get_abs_sub();
6660
6661 set_abs_sub( abs + sp );
6662
6663 // if player is in vehicle, (s)he must be shifted with vehicle too
6664 if( g->u.in_vehicle ) {
6665 g->u.setx( g->u.posx() - sp.x * SEEX );
6666 g->u.sety( g->u.posy() - sp.y * SEEY );
6667 }
6668
6669 g->shift_destination_preview( point( -sp.x * SEEX, -sp.y * SEEY ) );
6670
6671 shift_traps( tripoint( sp, 0 ) );
6672
6673 vehicle *remoteveh = g->remoteveh();
6674
6675 const int zmin = zlevels ? -OVERMAP_DEPTH : abs.z;
6676 const int zmax = zlevels ? OVERMAP_HEIGHT : abs.z;
6677 for( int gridz = zmin; gridz <= zmax; gridz++ ) {
6678 for( vehicle *veh : get_cache( gridz ).vehicle_list ) {
6679 veh->zones_dirty = true;
6680 }
6681 }
6682
6683 constexpr half_open_rectangle<point> boundaries_2d( point_zero, point( MAPSIZE_Y, MAPSIZE_X ) );
6684 const point shift_offset_pt( -sp.x * SEEX, -sp.y * SEEY );
6685
6686 // Clear vehicle list and rebuild after shift
6688 // Shift the map sx submaps to the right and sy submaps down.
6689 // sx and sy should never be bigger than +/-1.
6690 // absx and absy are our position in the world, for saving/loading purposes.
6691 for( int gridz = zmin; gridz <= zmax; gridz++ ) {
6692 clear_vehicle_list( gridz );
6693 shift_bitset_cache<MAPSIZE_X, SEEX>( get_cache( gridz ).map_memory_seen_cache, sp );
6694 shift_bitset_cache<MAPSIZE, 1>( get_cache( gridz ).field_cache, sp );
6695 if( sp.x >= 0 ) {
6696 for( int gridx = 0; gridx < my_MAPSIZE; gridx++ ) {
6697 if( sp.y >= 0 ) {
6698 for( int gridy = 0; gridy < my_MAPSIZE; gridy++ ) {
6699 if( ( sp.x > 0 && gridx == 0 ) || ( sp.y > 0 && gridy == 0 ) ) {
6700 submaps_with_active_items.erase( { abs.x + gridx, abs.y + gridy, gridz } );
6701 }
6702 if( gridx + sp.x < my_MAPSIZE && gridy + sp.y < my_MAPSIZE ) {
6703 copy_grid( tripoint( gridx, gridy, gridz ),
6704 tripoint( gridx + sp.x, gridy + sp.y, gridz ) );
6705 update_vehicle_list( get_submap_at_grid( {gridx, gridy, gridz} ), gridz );
6706 } else {
6707 loadn( tripoint( gridx, gridy, gridz ), true );
6708 }
6709 }
6710 } else { // sy < 0; work through it backwards
6711 for( int gridy = my_MAPSIZE - 1; gridy >= 0; gridy-- ) {
6712 if( ( sp.x > 0 && gridx == 0 ) || gridy == my_MAPSIZE - 1 ) {
6713 submaps_with_active_items.erase( { abs.x + gridx, abs.y + gridy, gridz } );
6714 }
6715 if( gridx + sp.x < my_MAPSIZE && gridy + sp.y >= 0 ) {
6716 copy_grid( tripoint( gridx, gridy, gridz ),
6717 tripoint( gridx + sp.x, gridy + sp.y, gridz ) );
6718 update_vehicle_list( get_submap_at_grid( { gridx, gridy, gridz } ), gridz );
6719 } else {
6720 loadn( tripoint( gridx, gridy, gridz ), true );
6721 }
6722 }
6723 }
6724 }
6725 } else { // sx < 0; work through it backwards
6726 for( int gridx = my_MAPSIZE - 1; gridx >= 0; gridx-- ) {
6727 if( sp.y >= 0 ) {
6728 for( int gridy = 0; gridy < my_MAPSIZE; gridy++ ) {
6729 if( gridx == my_MAPSIZE - 1 || ( sp.y > 0 && gridy == 0 ) ) {
6730 submaps_with_active_items.erase( { abs.x + gridx, abs.y + gridy, gridz } );
6731 }
6732 if( gridx + sp.x >= 0 && gridy + sp.y < my_MAPSIZE ) {
6733 copy_grid( tripoint( gridx, gridy, gridz ),
6734 tripoint( gridx + sp.x, gridy + sp.y, gridz ) );
6735 update_vehicle_list( get_submap_at_grid( { gridx, gridy, gridz } ), gridz );
6736 } else {
6737 loadn( tripoint( gridx, gridy, gridz ), true );
6738 }
6739 }
6740 } else { // sy < 0; work through it backwards
6741 for( int gridy = my_MAPSIZE - 1; gridy >= 0; gridy-- ) {
6742 if( gridx == my_MAPSIZE - 1 || gridy == my_MAPSIZE - 1 ) {
6743 submaps_with_active_items.erase( { abs.x + gridx, abs.y + gridy, gridz } );
6744 }
6745 if( gridx + sp.x >= 0 && gridy + sp.y >= 0 ) {
6746 copy_grid( tripoint( gridx, gridy, gridz ),
6747 tripoint( gridx + sp.x, gridy + sp.y, gridz ) );
6748 update_vehicle_list( get_submap_at_grid( { gridx, gridy, gridz } ), gridz );
6749 } else {
6750 loadn( tripoint( gridx, gridy, gridz ), true );
6751 }
6752 }
6753 }
6754 }
6755 }
6756 }
6757
6759
6760 g->setremoteveh( remoteveh );
6761
6762 if( !support_cache_dirty.empty() ) {
6763 shift_tripoint_set( support_cache_dirty, shift_offset_pt, boundaries_2d );
6764 }
6765}
void copy_grid(const tripoint &to, const tripoint &from)
Definition: map.cpp:7365
void shift_traps(const tripoint &shift)
As part of the map shifting, this shifts the trap locations stored in traplocs.
Definition: map.cpp:6516
template void shift_bitset_cache< MAPSIZE_X, SEEX >(std::bitset< MAPSIZE_X *MAPSIZE_X > &cache, const point &s)
static void shift_tripoint_set(std::set< tripoint > &set, const point &offset, const half_open_rectangle< point > &boundaries)
Definition: map.cpp:6575
template void shift_bitset_cache< MAPSIZE, 1 >(std::bitset< MAPSIZE *MAPSIZE > &cache, const point &s)
int remoteveh(player *, item *, bool, const tripoint &)
Definition: iuse.cpp:8245

References clear_vehicle_cache(), clear_vehicle_list(), copy_grid(), debugmsg, g, get_abs_sub(), get_cache(), get_submap_at_grid(), loadn(), MAPSIZE_X, MAPSIZE_Y, my_MAPSIZE, OVERMAP_DEPTH, OVERMAP_HEIGHT, point_zero, iuse::remoteveh(), reset_vehicle_cache(), SEEX, SEEY, set_abs_sub(), shift_bitset_cache< MAPSIZE, 1 >(), shift_bitset_cache< MAPSIZE_X, SEEX >(), shift_traps(), shift_tripoint_set(), submaps_with_active_items, support_cache_dirty, update_vehicle_list(), point::x, point::y, and zlevels.

Referenced by shift_traps(), and game::update_map().

◆ shift_traps()

void map::shift_traps ( const tripoint shift)
protected

As part of the map shifting, this shifts the trap locations stored in traplocs.

Parameters
shiftThe amount shifting in submap, the same as go into shift.

Definition at line 6516 of file map.cpp.

6517{
6518 // Offset needs to have sign opposite to shift direction
6519 const tripoint offset( -shift.x * SEEX, -shift.y * SEEY, -shift.z );
6520 for( auto iter = field_furn_locs.begin(); iter != field_furn_locs.end(); ) {
6521 tripoint &pos = *iter;
6522 pos += offset;
6523 if( inbounds( pos ) ) {
6524 ++iter;
6525 } else {
6526 iter = field_furn_locs.erase( iter );
6527 }
6528 }
6529 for( auto &traps : traplocs ) {
6530 for( auto iter = traps.begin(); iter != traps.end(); ) {
6531 tripoint &pos = *iter;
6532 pos += offset;
6533 if( inbounds( pos ) ) {
6534 ++iter;
6535 } else {
6536 // Theoretical enhancement: if this is not the last entry of the vector,
6537 // move the last entry into pos and remove the last entry instead of iter.
6538 // This would avoid moving all the remaining entries.
6539 iter = traps.erase( iter );
6540 }
6541 }
6542 }
6543}
void shift(const point &s)
Shift the map along the vector s.
Definition: map.cpp:6648

References field_furn_locs, inbounds(), SEEX, SEEY, shift(), and traplocs.

Referenced by shift().

◆ shift_vehicle_z()

void map::shift_vehicle_z ( vehicle veh,
int  z_shift 
)

Definition at line 6602 of file map.cpp.

6603{
6604
6605 tripoint src = veh.global_pos3();
6606 tripoint dst = src + tripoint_above * z_shift;
6607
6608 submap *src_submap = get_submap_at( src );
6609 submap *dst_submap = get_submap_at( dst );
6610
6611 int our_i = -1;
6612 for( size_t i = 0; i < src_submap->vehicles.size(); i++ ) {
6613 if( src_submap->vehicles[i].get() == &veh ) {
6614 our_i = i;
6615 break;
6616 }
6617 }
6618
6619 if( our_i == -1 ) {
6620 debugmsg( "shift_vehicle [%s] failed could not find vehicle", veh.name );
6621 return;
6622 }
6623
6624 for( auto &prt : veh.get_all_parts() ) {
6625 prt.part().precalc[0].z -= z_shift;
6626 }
6627
6628 veh.set_submap_moved( tripoint( dst.x / SEEX, dst.y / SEEY, dst.z ) );
6629 auto src_submap_veh_it = src_submap->vehicles.begin() + our_i;
6630 dst_submap->vehicles.push_back( std::move( *src_submap_veh_it ) );
6631 src_submap->vehicles.erase( src_submap_veh_it );
6632 dst_submap->is_uniform = false;
6634
6635 update_vehicle_list( dst_submap, dst.z );
6636
6637 level_cache &ch = get_cache( src.z );
6638 for( const vehicle *elem : ch.vehicle_list ) {
6639 if( elem == &veh ) {
6640 ch.vehicle_list.erase( &veh );
6641 ch.zone_vehicles.erase( &veh );
6642 break;
6643 }
6644 }
6645
6646}

References debugmsg, vehicle::get_all_parts(), get_cache(), get_submap_at(), vehicle::global_pos3(), invalidate_max_populated_zlev(), submap::is_uniform, avatar_action::move(), vehicle::name, SEEX, SEEY, vehicle::set_submap_moved(), tripoint_above, update_vehicle_list(), level_cache::vehicle_list, submap::vehicles, tripoint::x, tripoint::y, tripoint::z, and level_cache::zone_vehicles.

Referenced by vehicle::shift_zlevel().

◆ shoot()

void map::shoot ( const tripoint p,
projectile proj,
bool  hit_items 
)

Definition at line 3704 of file map.cpp.

3705{
3706 float initial_damage = 0.0;
3707 for( const damage_unit &dam : proj.impact ) {
3708 initial_damage += dam.amount * dam.damage_multiplier;
3709 initial_damage += dam.res_pen;
3710 }
3711 if( initial_damage < 0 ) {
3712 return;
3713 }
3714
3715 float dam = initial_damage;
3716
3717 if( has_flag( "ALARMED", p ) && !g->timed_events.queued( TIMED_EVENT_WANTED ) ) {
3718 sounds::sound( p, 30, sounds::sound_t::alarm, _( "an alarm sound!" ), true, "environment",
3719 "alarm" );
3720 const tripoint abs = ms_to_sm_copy( getabs( p ) );
3721 g->timed_events.add( TIMED_EVENT_WANTED, calendar::turn + 30_minutes, 0, abs );
3722 }
3723
3724 const bool inc = proj.has_effect( ammo_effect_INCENDIARY ) ||
3725 proj.impact.type_damage( DT_HEAT ) > 0;
3726 if( const optional_vpart_position vp = veh_at( p ) ) {
3727 dam = vp->vehicle().damage( vp->part_index(), dam, inc ? DT_HEAT : DT_STAB, hit_items );
3728 }
3729
3730 ter_id terrain = ter( p );
3731 ter_t ter = terrain.obj();
3732
3733 if( ter.bash.ranged ) {
3734 const ranged_bash_info &ri = *ter.bash.ranged;
3735 if( !hit_items && !check( ri.block_unaimed_chance ) ) {
3736 // Nothing, it's a miss
3737 } else if( ri.reduction_laser && proj.has_effect( ammo_effect_LASER ) ) {
3738 dam -= rng( ri.reduction_laser->min, ri.reduction_laser->max );
3739 } else {
3740 dam -= rng( ri.reduction.min, ri.reduction.max );
3741 if( dam > ri.destroy_threshold ) {
3742 bash_params params{0, false, true, hit_items, 1.0, false};
3743 bash_ter_success( p, params );
3744 }
3745 if( dam <= 0 && is_transparent( p ) && get_avatar().sees( p ) ) {
3746 add_msg( _( "The shot is stopped by the %s!" ), tername( p ) );
3747 }
3748 if( ri.flammable && inc ) {
3749 add_field( p, fd_fire, 1 );
3750 }
3751 }
3752 } else if( impassable( p ) && !is_transparent( p ) ) {
3753 bash( p, dam, false );
3754 // TODO: Preserve some residual damage when it makes sense.
3755 dam = 0;
3756 }
3757
3758 for( const ammo_effect_str_id &ae_id : proj.get_ammo_effects() ) {
3759 const ammo_effect &ae = *ae_id;
3760 if( ae.trail_field_type ) {
3761 if( x_in_y( ae.trail_chance, 100 ) ) {
3763 }
3764 }
3765 }
3766
3767 dam = std::max( 0.0f, dam );
3768
3769 // Check fields?
3770 const field_entry *fieldhit = get_field( p, fd_web );
3771 if( fieldhit != nullptr ) {
3772 if( inc ) {
3773 add_field( p, fd_fire, fieldhit->get_field_intensity() - 1 );
3774 } else if( dam > 5 + fieldhit->get_field_intensity() * 5 &&
3775 one_in( 5 - fieldhit->get_field_intensity() ) ) {
3776 dam -= rng( 1, 2 + fieldhit->get_field_intensity() * 2 );
3777 remove_field( p, fd_web );
3778 }
3779 }
3780
3781 // Rescale the damage
3782 if( dam <= 0 ) {
3783 proj.impact.damage_units.clear();
3784 return;
3785 } else if( dam < initial_damage ) {
3786 proj.impact.mult_damage( dam / static_cast<double>( initial_damage ) );
3787 }
3788
3789 //Projectiles with NO_ITEM_DAMAGE flag won't damage items at all
3790 if( !hit_items || !inbounds( p ) ) {
3791 return;
3792 }
3793
3794 // Make sure the message is sensible for the ammo effects. Lasers aren't projectiles.
3795 std::string damage_message;
3796 if( proj.has_effect( ammo_effect_LASER ) ) {
3797 damage_message = _( "laser beam" );
3798 } else if( proj.has_effect( ammo_effect_LIGHTNING ) ) {
3799 damage_message = _( "bolt of electricity" );
3800 } else if( proj.has_effect( ammo_effect_PLASMA ) ) {
3801 damage_message = _( "bolt of plasma" );
3802 } else {
3803 damage_message = _( "flying projectile" );
3804 }
3805
3806 smash_items( p, dam, damage_message, false );
3807}
avatar & get_avatar()
Definition: avatar.cpp:100
@ DT_STAB
Definition: damage.h:27
static const ammo_effect_str_id ammo_effect_LIGHTNING("LIGHTNING")
static const ammo_effect_str_id ammo_effect_LASER("LASER")
static const ammo_effect_str_id ammo_effect_INCENDIARY("INCENDIARY")
static const ammo_effect_str_id ammo_effect_PLASMA("PLASMA")
int check(unformattable)
Definition: fmtlib_core.h:1610
int trail_chance
Definition: ammo_effect.h:45
int trail_intensity_max
Definition: ammo_effect.h:44
int trail_intensity_min
Definition: ammo_effect.h:43
field_type_id trail_field_type
Definition: ammo_effect.h:40
std::vector< damage_unit > damage_units
Definition: damage.h:52
float type_damage(damage_type dt) const
Definition: damage.cpp:64
void mult_damage(double multiplier, bool pre_armor=false)
Definition: damage.cpp:48
float amount
Definition: damage.h:37
float damage_multiplier
Definition: damage.h:40
float res_pen
Definition: damage.h:38
const std::set< ammo_effect_str_id > & get_ammo_effects()
Definition: projectile.h:42
damage_instance impact
Definition: projectile.h:21
bool has_effect(const ammo_effect_str_id &id) const
Definition: projectile.h:55
bool flammable
Definition: mapdata.h:40
numeric_interval< int > reduction
Definition: mapdata.h:36
cata::optional< numeric_interval< int > > reduction_laser
Definition: mapdata.h:38
int destroy_threshold
Definition: mapdata.h:39
units::probability block_unaimed_chance
Definition: mapdata.h:41

References _, add_field(), add_msg(), sounds::alarm, ammo_effect_INCENDIARY, ammo_effect_LASER, ammo_effect_LIGHTNING, ammo_effect_PLASMA, damage_unit::amount, bash(), bash_ter_success(), ranged_bash_info::block_unaimed_chance, detail::check(), damage_unit::damage_multiplier, damage_instance::damage_units, ranged_bash_info::destroy_threshold, DT_HEAT, DT_STAB, fd_fire, fd_web, ranged_bash_info::flammable, g, projectile::get_ammo_effects(), get_avatar(), get_field(), field_entry::get_field_intensity(), getabs(), projectile::has_effect(), has_flag(), projectile::impact, impassable(), inbounds(), is_transparent(), ms_to_sm_copy(), damage_instance::mult_damage(), one_in(), ranged_bash_info::reduction, ranged_bash_info::reduction_laser, remove_field(), damage_unit::res_pen, rng(), sees(), smash_items(), sounds::sound(), ter(), tername(), terrain, TIMED_EVENT_WANTED, ammo_effect::trail_chance, ammo_effect::trail_field_type, ammo_effect::trail_intensity_max, ammo_effect::trail_intensity_min, calendar::turn, damage_instance::type_damage(), veh_at(), and x_in_y().

Referenced by ranged::execute_shaped_attack(), and projectile_attack().

◆ smash_items()

void map::smash_items ( const tripoint p,
int  power,
const std::string &  cause_message,
bool  do_destroy 
)

Tries to smash the items at the given tripoint.

Definition at line 2978 of file map.cpp.

2980{
2981 if( !has_items( p ) ) {
2982 return;
2983 }
2984
2985 // Keep track of how many items have been damaged, and what the first one is
2986 int items_damaged = 0;
2987 int items_destroyed = 0;
2988 std::string damaged_item_name;
2989
2990 // TODO: Bullets should be pretty much corpse-only
2991 constexpr const int min_destroy_threshold = 50;
2992
2993 std::vector<item> contents;
2994 map_stack items = i_at( p );
2995 for( auto i = items.begin(); i != items.end(); ) {
2996 // If the power is low or it's not an explosion, only pulp rezing corpses
2997 if( ( power < min_destroy_threshold || !do_destroy ) && !i->can_revive() ) {
2998 i++;
2999 continue;
3000 }
3001
3002 // Active explosives arbitrarily get double the destroy threshold
3003 bool is_active_explosive = i->active && i->type->get_use( "explosion" ) != nullptr;
3004 if( is_active_explosive && i->charges == 0 ) {
3005 i++;
3006 continue;
3007 }
3008
3009 const float material_factor = i->chip_resistance( true );
3010 // Intact non-rezing get a boost
3011 const float intact_mult = 2.0f -
3012 ( static_cast<float>( i->damage_level( i->max_damage() ) ) / i->max_damage() );
3013 const float destroy_threshold = min_destroy_threshold
3014 + material_factor * intact_mult
3015 + ( is_active_explosive ? min_destroy_threshold : 0 );
3016 // For pulping, only consider material resistance. Non-rezing can only be destroyed.
3017 const float pulp_threshold = i->can_revive() ? material_factor : destroy_threshold;
3018 // Active explosives that will explode this turn are indestructible (they are exploding "now")
3019 if( power < pulp_threshold ) {
3020 i++;
3021 continue;
3022 }
3023
3024 bool item_was_destroyed = false;
3025 float destroy_chance = ( power - pulp_threshold ) / 4.0;
3026
3027 const bool by_charges = i->count_by_charges();
3028 if( by_charges ) {
3029 destroy_chance *= i->charges_per_volume( 250_ml );
3030 if( x_in_y( destroy_chance, destroy_threshold ) ) {
3031 item_was_destroyed = true;
3032 }
3033 } else {
3034 const field_type_id type_blood = i->is_corpse() ? i->get_mtype()->bloodType() : fd_null;
3035 float roll = rng_float( 0.0, destroy_chance );
3036 if( roll >= destroy_threshold ) {
3037 item_was_destroyed = true;
3038 } else if( roll >= pulp_threshold ) {
3039 // Only pulp
3040 i->set_damage( i->max_damage() );
3041 // TODO: Blood streak cone away from explosion
3042 add_splash( type_blood, p, 1, destroy_chance );
3043 // If it was the first item to be damaged, note it
3044 if( items_damaged == 0 ) {
3045 damaged_item_name = i->tname();
3046 }
3047 items_damaged++;
3048 }
3049 }
3050
3051 // Remove them if they were damaged too much
3052 if( item_was_destroyed ) {
3053 // But save the contents, except for irremovable gunmods
3054 for( item *elem : i->contents.all_items_top() ) {
3055 if( !elem->is_irremovable() ) {
3056 contents.push_back( item( *elem ) );
3057 }
3058 }
3059
3060 if( items_damaged == 0 ) {
3061 damaged_item_name = i->tname();
3062 }
3063 i = i_rem( p, i );
3064 items_damaged++;
3065 items_destroyed++;
3066 } else {
3067 i++;
3068 }
3069 }
3070
3071 // Let the player know that the item was damaged if they can see it.
3072 if( items_destroyed > 1 && g->u.sees( p ) ) {
3073 add_msg( m_bad, _( "The %s destroys several items!" ), cause_message );
3074 } else if( items_destroyed == 1 && items_damaged == 1 && g->u.sees( p ) ) {
3075 //~ %1$s: the cause of destruction, %2$s: destroyed item name
3076 add_msg( m_bad, _( "The %1$s destroys the %2$s!" ), cause_message, damaged_item_name );
3077 } else if( items_damaged > 1 && g->u.sees( p ) ) {
3078 add_msg( m_bad, _( "The %s damages several items." ), cause_message );
3079 } else if( items_damaged == 1 && g->u.sees( p ) ) {
3080 //~ %1$s: the cause of damage, %2$s: damaged item name
3081 add_msg( m_bad, _( "The %1$s damages the %2$s." ), cause_message, damaged_item_name );
3082 }
3083
3084 for( const item &it : contents ) {
3085 add_item_or_charges( p, it );
3086 }
3087}
void add_splash(const field_type_id &type, const tripoint &center, int radius, int intensity)
Definition: map.cpp:5506

References _, add_item_or_charges(), add_msg(), add_splash(), item_contents::all_items_top(), item_stack::begin(), item::contents, item_stack::end(), fd_null, g, has_items(), i_at(), i_rem(), m_bad, rng_float(), and x_in_y().

Referenced by explosion_handler::do_blast(), explosion_handler::do_blast_new(), move_vehicle(), and shoot().

◆ spawn_an_item() [1/2]

void map::spawn_an_item ( const point p,
item  new_item,
int  charges,
int  damlevel 
)
inline

Definition at line 1280 of file map.h.

1280 {
1281 spawn_an_item( tripoint( p, abs_sub.z ), new_item, charges, damlevel );
1282 }
item & spawn_an_item(const tripoint &p, item new_item, int charges, int damlevel)
Definition: map.cpp:4124

References abs_sub, spawn_an_item(), and tripoint::z.

◆ spawn_an_item() [2/2]

item & map::spawn_an_item ( const tripoint p,
item  new_item,
int  charges,
int  damlevel 
)

Definition at line 4124 of file map.cpp.

4126{
4127 if( charges && new_item.charges > 0 ) {
4128 //let's fail silently if we specify charges for an item that doesn't support it
4129 new_item.charges = charges;
4130 }
4131 new_item = new_item.in_its_container();
4132 if( ( new_item.made_of( LIQUID ) && has_flag( "SWIMMABLE", p ) ) ||
4133 has_flag( "DESTROY_ITEM", p ) ) {
4134 return null_item_reference();
4135 }
4136
4137 new_item.set_damage( damlevel );
4138
4139 return add_item_or_charges( p, new_item );
4140}
item & set_damage(int qty)
Filter setting damage constrained by min_damage and max_damage.
Definition: item.cpp:710
item in_its_container() const
Returns this item into its default container.
Definition: item.cpp:837

References add_item_or_charges(), item::charges, has_flag(), item::in_its_container(), LIQUID, item::made_of(), null_item_reference(), and item::set_damage().

Referenced by salvage_actor::cut_up(), spawn_an_item(), and spawn_item().

◆ spawn_artifact()

void map::spawn_artifact ( const tripoint p)

Definition at line 4163 of file map.cpp.

4164{
4166}
itype_id new_artifact()
Definition: artifact.cpp:677

References add_item_or_charges(), new_artifact(), and calendar::start_of_cataclysm.

Referenced by draw_mine(), and draw_temple().

◆ spawn_item() [1/4]

void map::spawn_item ( const point p,
const itype_id type_id,
unsigned  quantity = 1,
int  charges = 0,
const time_point birthday = calendar::start_of_cataclysm,
int  damlevel = 0 
)
inline

Definition at line 1233 of file map.h.

1235 {
1236 spawn_item( tripoint( p, abs_sub.z ), type_id, quantity, charges, birthday, damlevel );
1237 }

References abs_sub, spawn_item(), and tripoint::z.

◆ spawn_item() [2/4]

void map::spawn_item ( const point p,
const std::string &  type_id,
unsigned  quantity = 1,
int  charges = 0,
const time_point birthday = calendar::start_of_cataclysm,
int  damlevel = 0 
)
inline

Definition at line 1246 of file map.h.

1248 {
1249 spawn_item( tripoint( p, abs_sub.z ), type_id, quantity, charges, birthday, damlevel );
1250 }

References abs_sub, spawn_item(), and tripoint::z.

◆ spawn_item() [3/4]

void map::spawn_item ( const tripoint p,
const itype_id type_id,
unsigned  quantity = 1,
int  charges = 0,
const time_point birthday = calendar::start_of_cataclysm,
int  damlevel = 0 
)

Definition at line 4173 of file map.cpp.

4176{
4177 if( type_id.is_null() ) {
4178 return;
4179 }
4180
4181 if( item_is_blacklisted( type_id ) ) {
4182 return;
4183 }
4184 // recurse to spawn (quantity - 1) items
4185 for( size_t i = 1; i < quantity; i++ ) {
4186 spawn_item( p, type_id, 1, charges, birthday, damlevel );
4187 }
4188 // spawn the item
4189 item new_item( type_id, birthday );
4190 if( one_in( 3 ) && new_item.has_flag( "VARSIZE" ) ) {
4191 new_item.set_flag( "FIT" );
4192 }
4193
4194 spawn_an_item( p, new_item, charges, damlevel );
4195}
bool is_null() const
Returns whether this represents the id of the null-object (in which case it's the null-id).
Definition: string_id.h:317
bool item_is_blacklisted(const itype_id &id)

References item::has_flag(), string_id< T >::is_null(), item_is_blacklisted(), one_in(), item::set_flag(), spawn_an_item(), and spawn_item().

Referenced by computer_session::action_extract_rad_source(), jmapgen_spawn_item::apply(), MapExtras::burned_ground_parser(), talk_function::buy_100_logs(), talk_function::buy_10_logs(), activity_handlers::chop_planks_finish(), create_anomaly(), create_burnproducts(), iexamine::curtains(), MapExtras::dead_vegetation_parser(), game::disable_robot(), construct::done_window_curtains(), draw_lab(), draw_office_tower(), explosion_handler::emp_blast(), iexamine::fertilize_plant(), dig_activity_actor::finish(), iexamine::flower_marloss(), activity_handlers::hacksaw_finish(), vehicle::handle_trap(), make_rubble(), mapgen_cavern(), mapgen_tutorial(), MapExtras::mx_casings(), MapExtras::mx_drugdeal(), MapExtras::mx_grave(), MapExtras::mx_mayhem(), MapExtras::mx_minefield(), MapExtras::mx_roadworks(), om_cutdown_trees(), trap::on_disarmed(), activity_handlers::oxytorch_finish(), pick_plant(), mission_start::place_deposit_box(), MapExtras::place_fumarole(), mission_start::place_priest_diary(), place_vending(), activity_handlers::pry_nails_finish(), mission_start::ranch_nurse_1(), mission_start::ranch_nurse_2(), mission_start::ranch_scavenger_1(), mission_start::ranch_scavenger_2(), mission_start::ranch_scavenger_3(), iexamine::recycle_compactor(), iexamine::shrub_marloss(), spawn_item(), iexamine::tree_hickory(), iexamine::tree_marloss(), try_remove_bear_trap(), try_remove_heavysnare(), try_remove_lightsnare(), unroll_digging(), and game::vertical_move().

◆ spawn_item() [4/4]

void map::spawn_item ( const tripoint p,
const std::string &  type_id,
unsigned  quantity = 1,
int  charges = 0,
const time_point birthday = calendar::start_of_cataclysm,
int  damlevel = 0 
)
inline

Definition at line 1241 of file map.h.

1243 {
1244 spawn_item( p, itype_id( type_id ), quantity, charges, birthday, damlevel );
1245 }

References itype_id, and spawn_item().

◆ spawn_items() [1/2]

void map::spawn_items ( const point p,
const std::vector< item > &  new_items 
)
inline

Definition at line 1356 of file map.h.

1356 {
1357 spawn_items( tripoint( p, abs_sub.z ), new_items );
1358 }

References abs_sub, spawn_items(), and tripoint::z.

◆ spawn_items() [2/2]

std::vector< item * > map::spawn_items ( const tripoint p,
const std::vector< item > &  new_items 
)

Definition at line 4142 of file map.cpp.

4143{
4144 std::vector<item *> ret;
4145 if( !inbounds( p ) || has_flag( "DESTROY_ITEM", p ) ) {
4146 return ret;
4147 }
4148 const bool swimmable = has_flag( "SWIMMABLE", p );
4149 for( const item &new_item : new_items ) {
4150
4151 if( new_item.made_of( LIQUID ) && swimmable ) {
4152 continue;
4153 }
4154 item &it = add_item_or_charges( p, new_item );
4155 if( !it.is_null() ) {
4156 ret.push_back( &it );
4157 }
4158 }
4159
4160 return ret;
4161}
bool is_null() const
Definition: item.cpp:728

References add_item_or_charges(), has_flag(), inbounds(), item::is_null(), LIQUID, and cata::hash64_detail::ret.

Referenced by jmapgen_loot::apply(), bash_furn_success(), bash_items(), bash_ter_success(), complete_construction(), construct::done_deconstruct(), dig_activity_actor::finish(), dig_channel_activity_actor::finish(), talk_function::loot_building(), MapExtras::mx_casings(), MapExtras::mx_corpses(), process_fields_in_submap(), put_items_from_loc(), veh_utils::repair_part(), smash(), and spawn_items().

◆ spawn_monsters()

void map::spawn_monsters ( bool  ignore_sight)

Spawn monsters from submap spawn points and from the overmap.

Parameters
ignore_sightIf true, monsters may spawn in the view of the player character (useful when the whole map has been loaded instead, e.g. when starting a new game, or after teleportation or after moving vertically). If false, monsters are not spawned in view of player character.

Definition at line 7563 of file map.cpp.

7564{
7565 const int zmin = zlevels ? -OVERMAP_DEPTH : abs_sub.z;
7566 const int zmax = zlevels ? OVERMAP_HEIGHT : abs_sub.z;
7567 tripoint gp;
7568 int &gx = gp.x;
7569 int &gy = gp.y;
7570 int &gz = gp.z;
7571 for( gz = zmin; gz <= zmax; gz++ ) {
7572 for( gx = 0; gx < my_MAPSIZE; gx++ ) {
7573 for( gy = 0; gy < my_MAPSIZE; gy++ ) {
7574 spawn_monsters_submap( gp, ignore_sight );
7575 }
7576 }
7577 }
7578}
void spawn_monsters_submap(const tripoint &gp, bool ignore_sight)
Definition: map.cpp:7508

References abs_sub, my_MAPSIZE, OVERMAP_DEPTH, OVERMAP_HEIGHT, spawn_monsters_submap(), tripoint::x, tripoint::y, tripoint::z, and zlevels.

Referenced by game::do_turn(), editmap::mapgen_preview(), game::place_player_overmap(), game::start_game(), game::update_map(), and game::vertical_shift().

◆ spawn_monsters_submap()

void map::spawn_monsters_submap ( const tripoint gp,
bool  ignore_sight 
)
private

Definition at line 7508 of file map.cpp.

7509{
7510 // Load unloaded monsters
7511 // TODO: fix point types
7513
7514 // Only spawn new monsters after existing monsters are loaded.
7515 // TODO: fix point types
7516 auto groups = overmap_buffer.groups_at( tripoint_abs_sm( gp + abs_sub.xy() ) );
7517 for( auto &mgp : groups ) {
7518 spawn_monsters_submap_group( gp, *mgp, ignore_sight );
7519 }
7520
7521 submap *const current_submap = get_submap_at_grid( gp );
7522 const tripoint gp_ms = sm_to_ms_copy( gp );
7523
7524 for( auto &i : current_submap->spawns ) {
7525 const tripoint center = gp_ms + i.pos;
7527
7528 for( int j = 0; j < i.count; j++ ) {
7529 monster tmp( i.type );
7530 tmp.mission_id = i.mission_id;
7531 if( i.name != "NONE" ) {
7532 tmp.unique_name = i.name;
7533 }
7534 if( i.friendly ) {
7535 tmp.friendly = -1;
7536 }
7537
7538 const auto valid_location = [&]( const tripoint & p ) {
7539 // Checking for creatures via g is only meaningful if this is the main game map.
7540 // If it's some local map instance, the coordinates will most likely not even match.
7541 return ( !g || &get_map() != this || !g->critter_at( p ) ) && tmp.can_move_to( p );
7542 };
7543
7544 const auto place_it = [&]( const tripoint & p ) {
7545 monster *const placed = g->place_critter_at( make_shared_fast<monster>( tmp ), p );
7546 if( placed ) {
7547 placed->on_load();
7548 }
7549 };
7550
7551 // First check out defined spawn location for a valid placement, and if that doesn't work
7552 // then fall back to picking a random point that is a valid location.
7553 if( valid_location( center ) ) {
7554 place_it( center );
7555 } else if( const cata::optional<tripoint> pos = random_point( points, valid_location ) ) {
7556 place_it( *pos );
7557 }
7558 }
7559 }
7560 current_submap->spawns.clear();
7561}
void spawn_monsters_submap_group(const tripoint &gp, mongroup &group, bool ignore_sight)
Definition: map.cpp:7374
void on_load()
Retroactively update monster.
Definition: monster.cpp:2985
std::vector< mongroup * > groups_at(const tripoint_abs_sm &p)
Monster groups at p - absolute submap coordinates.
void spawn_monster(const tripoint_abs_sm &p)
Spawn monsters from the overmap onto the main map (game::m).

References abs_sub, monster::can_move_to(), center, monster::friendly, g, get_map(), get_submap_at_grid(), overmapbuffer::groups_at(), monster::mission_id, monster::on_load(), overmap_buffer, points_in_radius(), random_point(), sm_to_ms_copy(), overmapbuffer::spawn_monster(), spawn_monsters_submap_group(), submap::spawns, monster::unique_name, and tripoint::xy().

Referenced by spawn_monsters().

◆ spawn_monsters_submap_group()

void map::spawn_monsters_submap_group ( const tripoint gp,
mongroup group,
bool  ignore_sight 
)
private

Definition at line 7374 of file map.cpp.

7375{
7376 const int s_range = std::min( HALF_MAPSIZE_X,
7377 g->u.sight_range( g->light_level( g->u.posz() ) ) );
7378 int pop = group.population;
7379 std::vector<tripoint> locations;
7380 if( !ignore_sight ) {
7381 // If the submap is one of the outermost submaps, assume that monsters are
7382 // invisible there.
7383 if( gp.x == 0 || gp.y == 0 || gp.x + 1 == MAPSIZE || gp.y + 1 == MAPSIZE ) {
7384 ignore_sight = true;
7385 }
7386 }
7387
7388 if( gp.z != g->u.posz() ) {
7389 // Note: this is only OK because 3D vision isn't a thing yet
7390 ignore_sight = true;
7391 }
7392
7393 static const auto allow_on_terrain = [&]( const tripoint & p ) {
7394 // TODO: flying creatures should be allowed to spawn without a floor,
7395 // but the new creature is created *after* determining the terrain, so
7396 // we can't check for it here.
7397 return passable( p ) && has_floor( p );
7398 };
7399
7400 // If the submap is uniform, we can skip many checks
7401 const submap *current_submap = get_submap_at_grid( gp );
7402 bool ignore_terrain_checks = false;
7403 bool ignore_inside_checks = gp.z < 0;
7404 if( current_submap->is_uniform ) {
7405 const tripoint upper_left{ SEEX * gp.x, SEEY * gp.y, gp.z };
7406 if( !allow_on_terrain( upper_left ) ||
7407 ( !ignore_inside_checks && has_flag_ter_or_furn( TFLAG_INDOORS, upper_left ) ) ) {
7408 const tripoint glp = getabs( gp );
7409 dbg( DL::Warn ) << "Empty locations for group " << group.type.str()
7410 << " at uniform submap " << gp << " global " << glp;
7411 return;
7412 }
7413
7414 ignore_terrain_checks = true;
7415 ignore_inside_checks = true;
7416 }
7417
7418 for( int x = 0; x < SEEX; ++x ) {
7419 for( int y = 0; y < SEEY; ++y ) {
7420 int fx = x + SEEX * gp.x;
7421 int fy = y + SEEY * gp.y;
7422 tripoint fp{ fx, fy, gp.z };
7423 if( g->critter_at( fp ) != nullptr ) {
7424 continue; // there is already some creature
7425 }
7426
7427 if( !ignore_terrain_checks && !allow_on_terrain( fp ) ) {
7428 continue; // solid area, impassable
7429 }
7430
7431 if( !ignore_sight && sees( g->u.pos(), fp, s_range ) ) {
7432 continue; // monster must spawn outside the viewing range of the player
7433 }
7434
7435 if( !ignore_inside_checks && has_flag_ter_or_furn( TFLAG_INDOORS, fp ) ) {
7436 continue; // monster must spawn outside.
7437 }
7438
7439 locations.push_back( fp );
7440 }
7441 }
7442
7443 if( locations.empty() ) {
7444 // TODO: what now? there is no possible place to spawn monsters, most
7445 // likely because the player can see all the places.
7446 const tripoint glp = getabs( gp );
7447 dbg( DL::Warn ) << "Empty locations for group " << group.type.str()
7448 << " at " << gp << " global " << glp;
7449 // Just kill the group. It's not like we're removing existing monsters
7450 // Unless it's a horde - then don't kill it and let it spawn behind a tree or smoke cloud
7451 if( !group.horde ) {
7452 group.clear();
7453 }
7454
7455 return;
7456 }
7457
7458 if( pop ) {
7459 // Populate the group from its population variable.
7460 for( int m = 0; m < pop; m++ ) {
7462 if( !spawn_details.name ) {
7463 continue;
7464 }
7465 monster tmp( spawn_details.name );
7466
7467 // If a monster came from a horde population, configure them to always be willing to rejoin a horde.
7468 if( group.horde ) {
7469 tmp.set_horde_attraction( MHA_ALWAYS );
7470 }
7471 for( int i = 0; i < spawn_details.pack_size; i++ ) {
7472 group.monsters.push_back( tmp );
7473 }
7474 }
7475 }
7476
7477 // Find horde's target submap
7478 // TODO: fix point types
7479 tripoint horde_target( tripoint( -abs_sub.xy(), abs_sub.z ) + group.target.xy().raw() );
7480 sm_to_ms( horde_target );
7481 for( auto &tmp : group.monsters ) {
7482 for( int tries = 0; tries < 10 && !locations.empty(); tries++ ) {
7484 if( !tmp.can_move_to( p ) ) {
7485 continue; // target can not contain the monster
7486 }
7487 if( group.horde ) {
7488 // Give monster a random point near horde's expected destination
7489 const tripoint rand_dest = horde_target +
7490 point( rng( 0, SEEX ), rng( 0, SEEY ) );
7491 const int turns = rl_dist( p, rand_dest ) + group.interest;
7492 tmp.wander_to( rand_dest, turns );
7493 add_msg( m_debug, "%s targeting %d,%d,%d", tmp.disp_name(),
7494 tmp.wander_pos.x, tmp.wander_pos.y, tmp.wander_pos.z );
7495 }
7496
7497 monster *const placed = g->place_critter_at( make_shared_fast<monster>( tmp ), p );
7498 if( placed ) {
7499 placed->on_load();
7500 }
7501 break;
7502 }
7503 }
7504 // indicates the group is empty, and can be removed later
7505 group.clear();
7506}
void sm_to_ms(int &x, int &y)
static constexpr int HALF_MAPSIZE_X
@ MHA_ALWAYS
Definition: monster.h:75
generic_factory< overmap_location > locations("overmap location")

References abs_sub, add_msg(), dbg, g, get_submap_at_grid(), getabs(), MonsterGroupManager::GetResultFromGroup(), HALF_MAPSIZE_X, has_flag_ter_or_furn(), has_floor(), submap::is_uniform, anonymous_namespace{overmap_location.cpp}::locations, m_debug, MAPSIZE, MHA_ALWAYS, MonsterGroupResult::name, monster::on_load(), MonsterGroupResult::pack_size, passable(), random_entry_removed(), rl_dist(), rng(), sees(), SEEX, SEEY, monster::set_horde_attraction(), sm_to_ms(), TFLAG_INDOORS, Warn, tripoint::x, tripoint::xy(), tripoint::y, and tripoint::z.

Referenced by spawn_monsters_submap().

◆ spawn_natural_artifact()

void map::spawn_natural_artifact ( const tripoint p,
artifact_natural_property  prop 
)

Definition at line 4168 of file map.cpp.

4169{
4171}
itype_id new_natural_artifact(artifact_natural_property prop)
Definition: artifact.cpp:931

References add_item_or_charges(), new_natural_artifact(), and calendar::start_of_cataclysm.

Referenced by debug_menu::debug(), and MapExtras::mx_portal_in().

◆ spread_gas()

void map::spread_gas ( field_entry cur,
const tripoint p,
int  percent_spread,
const time_duration outdoor_age_speedup,
scent_block sblk 
)
private

Definition at line 249 of file map_field.cpp.

251{
252 map &here = get_map();
253 // TODO: fix point types
254 const oter_id &cur_om_ter =
256 const bool sheltered = g->is_sheltered( p );
258 const int winddirection = weather.winddirection;
259 const int windpower = get_local_windpower( weather.windspeed, cur_om_ter, p, winddirection,
260 sheltered );
261
262 const int current_intensity = cur.get_field_intensity();
263 const field_type_id ft_id = cur.get_field_type();
264
265 const int scent_neutralize = ft_id->get_intensity_level( current_intensity -
267
268 if( scent_neutralize > 0 ) {
269 // modify scents by neutralization value (minus)
270 for( const tripoint &tmp : points_in_radius( p, 1 ) ) {
271 sblk.apply_gas( tmp, scent_neutralize );
272 }
273 }
274
275 // Dissipate faster outdoors.
276 if( is_outside( p ) ) {
277 const time_duration current_age = cur.get_field_age();
278 cur.set_field_age( current_age + outdoor_age_speedup );
279 }
280
281 // Bail out if we don't meet the spread chance or required intensity.
282 if( current_intensity <= 1 || rng( 1, 100 - windpower ) > percent_spread ) {
283 return;
284 }
285
286 // First check if we can fall
287 // TODO: Make fall and rise chances parameters to enable heavy/light gas
288 if( zlevels && p.z > -OVERMAP_DEPTH ) {
289 const tripoint down{ p.xy(), p.z - 1 };
290 maptile down_tile = maptile_at_internal( down );
291 if( gas_can_spread_to( cur, down_tile ) && valid_move( p, down, true, true ) ) {
292 gas_spread_to( cur, down_tile, down );
293 return;
294 }
295 }
296
297 auto neighs = get_neighbors( p );
298 size_t end_it = static_cast<size_t>( rng( 0, neighs.size() - 1 ) );
299 std::vector<size_t> spread;
300 std::vector<size_t> neighbour_vec;
301 // Then, spread to a nearby point.
302 // If not possible (or randomly), try to spread up
303 // Wind direction will block the field spreading into the wind.
304 // Start at end_it + 1, then wrap around until all elements have been processed.
305 for( size_t i = ( end_it + 1 ) % neighs.size(), count = 0;
306 count != neighs.size();
307 i = ( i + 1 ) % neighs.size(), count++ ) {
308 const auto &neigh = neighs[i];
309 if( gas_can_spread_to( cur, neigh.second ) ) {
310 spread.push_back( i );
311 }
312 }
313 auto maptiles = get_wind_blockers( winddirection, p );
314 // Three map tiles that are facing the wind direction.
315 const maptile remove_tile = std::get<0>( maptiles );
316 const maptile remove_tile2 = std::get<1>( maptiles );
317 const maptile remove_tile3 = std::get<2>( maptiles );
318 if( !spread.empty() && ( !zlevels || one_in( spread.size() ) ) ) {
319 // Construct the destination from offset and p
320 if( g->is_sheltered( p ) || windpower < 5 ) {
321 std::pair<tripoint, maptile> &n = neighs[ random_entry( spread ) ];
322 gas_spread_to( cur, n.second, n.first );
323 } else {
324 end_it = static_cast<size_t>( rng( 0, neighs.size() - 1 ) );
325 // Start at end_it + 1, then wrap around until all elements have been processed.
326 for( size_t i = ( end_it + 1 ) % neighs.size(), count = 0;
327 count != neighs.size();
328 i = ( i + 1 ) % neighs.size(), count++ ) {
329 const auto &neigh = neighs[i].second;
330 if( ( neigh.pos_.x != remove_tile.pos_.x && neigh.pos_.y != remove_tile.pos_.y ) ||
331 ( neigh.pos_.x != remove_tile2.pos_.x && neigh.pos_.y != remove_tile2.pos_.y ) ||
332 ( neigh.pos_.x != remove_tile3.pos_.x && neigh.pos_.y != remove_tile3.pos_.y ) ) {
333 neighbour_vec.push_back( i );
334 } else if( x_in_y( 1, std::max( 2, windpower ) ) ) {
335 neighbour_vec.push_back( i );
336 }
337 }
338 if( !neighbour_vec.empty() ) {
339 std::pair<tripoint, maptile> &n = neighs[neighbour_vec[rng( 0, neighbour_vec.size() - 1 )]];
340 gas_spread_to( cur, n.second, n.first );
341 }
342 }
343 } else if( zlevels && p.z < OVERMAP_HEIGHT ) {
344 const tripoint up{ p.xy(), p.z + 1 };
345 maptile up_tile = maptile_at_internal( up );
346 if( gas_can_spread_to( cur, up_tile ) && valid_move( p, up, true, true ) ) {
347 gas_spread_to( cur, up_tile, up );
348 }
349 }
350}
std::tuple< maptile, maptile, maptile > get_wind_blockers(const int &winddirection, const tripoint &pos)
Definition: map_field.cpp:1891
void gas_spread_to(field_entry &cur, maptile &dst, const tripoint &p)
Definition: map_field.cpp:223
bool gas_can_spread_to(field_entry &cur, const maptile &dst)
Definition: map_field.cpp:211
coords::coord_point< tripoint, coords::origin::abs, coords::omt > tripoint_abs_omt
Definition: coordinates.h:493
double get_local_windpower(double windpower, const oter_id &omter, const tripoint &location, const int &winddirection, bool sheltered)
Definition: weather.cpp:938
const field_intensity_level & get_intensity_level(int level=0) const
Definition: field_type.cpp:130
point pos_
Definition: submap.h:272
void apply_gas(const tripoint &p, const int nintensity=0)
Definition: scent_block.h:77

References scent_block::apply_gas(), detail::count(), g, gas_can_spread_to(), gas_spread_to(), field_entry::get_field_age(), field_entry::get_field_intensity(), field_entry::get_field_type(), field_type::get_intensity_level(), get_local_windpower(), get_map(), get_neighbors(), get_weather(), get_wind_blockers(), getabs(), is_outside(), maptile_at_internal(), ms_to_omt_copy(), one_in(), overmap_buffer, OVERMAP_DEPTH, OVERMAP_HEIGHT, points_in_radius(), maptile::pos_, random_entry(), rng(), field_intensity_level::scent_neutralization, field_entry::set_field_age(), overmapbuffer::ter(), valid_move(), point::x, x_in_y(), tripoint::xy(), point::y, tripoint::z, and zlevels.

Referenced by process_fields_in_submap().

◆ stored_volume()

units::volume map::stored_volume ( const tripoint p)

Definition at line 4203 of file map.cpp.

4204{
4205 return i_at( p ).stored_volume();
4206}
units::volume stored_volume() const
Total volume of the items here.
Definition: item_stack.cpp:98

References i_at(), and item_stack::stored_volume().

◆ support_dirty()

void map::support_dirty ( const tripoint p)
private

Definition at line 2262 of file map.cpp.

2263{
2264 if( zlevels ) {
2265 support_cache_dirty.insert( p );
2266 }
2267}

References support_cache_dirty, and zlevels.

Referenced by add_field(), add_item_or_charges(), drop_furniture(), furn_set(), ter_set(), and update_suspension_cache().

◆ supports_above()

bool map::supports_above ( const tripoint p) const

Does this tile support vehicles and furniture above it.

Definition at line 2015 of file map.cpp.

2016{
2017 const maptile tile = maptile_at( p );
2018 const ter_t &ter = tile.get_ter_t();
2019 if( ter.movecost == 0 ) {
2020 return true;
2021 }
2022
2023 const furn_id frn_id = tile.get_furn();
2024 if( frn_id != f_null ) {
2025 const furn_t &frn = frn_id.obj();
2026 if( frn.movecost < 0 ) {
2027 return true;
2028 }
2029 }
2030
2031 return veh_at( p ).has_value();
2032}
constexpr bool has_value() const noexcept
Definition: optional.h:120
furn_id get_furn() const
Definition: submap.h:285

References f_null, maptile::get_furn(), maptile::get_ter_t(), cata::optional< T >::has_value(), maptile_at(), map_data_common_t::movecost, int_id< T >::obj(), ter(), and veh_at().

Referenced by vehicle::check_falling_or_floating(), and drop_furniture().

◆ ter() [1/2]

ter_id map::ter ( const point p) const
inline

Definition at line 850 of file map.h.

850 {
851 return ter( tripoint( p, abs_sub.z ) );
852 }

References abs_sub, ter(), and tripoint::z.

◆ ter() [2/2]

ter_id map::ter ( const tripoint p) const

Definition at line 1493 of file map.cpp.

1494{
1495 if( !inbounds( p ) ) {
1496 return t_null;
1497 }
1498
1499 point l;
1500 submap *const current_submap = get_submap_at( p, l );
1501
1502 return current_submap->get_ter( l );
1503}

References get_submap_at(), submap::get_ter(), inbounds(), and t_null.

Referenced by computer_session::action_conveyor(), computer_session::action_data_anal(), computer_session::action_deactivate_shock_vent(), computer_session::action_elevator_on(), computer_session::action_extract_rad_source(), computer_session::action_geiger(), computer_session::action_irradiator(), computer_session::action_sample(), computer_session::action_srcf_elevator(), computer_session::action_srcf_seal(), actualize(), ter_furn_transform::add_all_messages(), add_boardable(), cata_event_dispatch::avatar_moves(), bash_rating(), bash_resistance(), bash_strength(), bash_ter_furn(), bash_ter_success(), board_up(), MapExtras::burned_ground_parser(), activity_handlers::burrow_finish(), can_construct(), can_do_activity_there(), can_examine_at(), iexamine::cardreader(), iexamine::cardreader_foodplace(), construct::check_deconstruct(), vehicle::autodrive_controller::check_drivable(), activity_handlers::chop_logs_finish(), chop_tree_activity(), close_door(), complete_construction(), coverage(), iexamine::curtains(), MapExtras::dead_vegetation_parser(), determine_wall_corner(), displace_water(), construct::done_deconstruct(), construct::done_digormine_stair(), construct::done_extract_maybe_revert_to_dirt(), construct::done_mine_upstair(), editmap_hilight::draw(), draw_connections(), draw_lab(), editmap::draw_main_ui_overlay(), draw_mine(), draw_temple(), draw_triffid(), avatar_action::eat_here(), explosion_handler::emp_blast(), examine(), game::examine(), game::extended_description(), computer_session::failure_destroy_data(), computer_session::failure_pump_explode(), computer_session::failure_pump_leak(), feature< ter_id >(), talk_function::field_plant(), activity_handlers::fill_liquid_do_turn(), activity_handlers::fill_pit_finish(), find_base_construction(), game::find_or_make_stairs(), find_potential_computer_point(), dig_activity_actor::finish(), dig_channel_activity_actor::finish(), hacking_activity_actor::finish(), Character::floor_bedding_warmth(), fromPumpFuel(), iexamine::fswitch(), gas_can_spread_to(), generic_multi_activity_locations(), get_changed_ids_from_update(), get_hack_type(), get_harvest(), get_harvest_names(), get_known_connections(), get_roof(), get_ter_transforms_into(), iexamine::getGasPumpByNumber(), iexamine::getNearFilledGasTank(), getNearPumpCount(), activity_handlers::hacksaw_finish(), has_flag_ter(), has_neighbor(), has_pre_terrain(), hit_with_acid(), advanced_inv_area::init(), is_bashable(), is_bashable_ter(), anonymous_namespace{gates.cpp}::gate_data::is_suitable_wall(), is_suspension_valid(), iexamine::ledge(), talk_function::loot_building(), mapgen_ants_generic(), mapgen_lake_shore(), fungal_effects::marlossify(), map_stack::max_volume(), avatar_action::move(), move_cost(), move_vehicle(), MapExtras::mx_grove(), MapExtras::mx_helicopter(), MapExtras::mx_house_spider(), MapExtras::mx_house_wasp(), MapExtras::mx_portal_in(), MapExtras::mx_shrubbery(), iexamine::nanofab(), obstacle_coverage(), om_cutdown_trees(), om_harvest_ter(), open(), open_door(), gates::open_gate(), activity_handlers::oxytorch_finish(), iexamine::pedestal_wyrm(), tutorial_game::per_turn(), activity_handlers::pickaxe_finish(), iexamine::pit(), iexamine::pit_covered(), mission_start::place_deposit_box(), place_items(), game::place_player(), game::print_fields_info(), game::print_graffiti_info(), game::print_terrain_info(), process_fields_in_submap(), process_items_in_submap(), produce_sap(), activity_handlers::pry_nails_finish(), rad_scorch(), resolve_regional_terrain_and_furniture(), restock_fruits(), mission_start::reveal_lab_train_depot(), shoot(), supports_above(), ter(), tername(), iexamine::toPumpFuel(), ter_furn_transform::transform(), translate(), translate_radius(), trap_set(), turnOnSelectedPump(), Character::update_bodytemp(), update_suspension_cache(), editmap::update_view_with_help(), vehicle_wheel_traction(), game::vertical_move(), game::walk_move(), and water_from().

◆ ter_set() [1/2]

bool map::ter_set ( const point p,
const ter_id new_terrain 
)
inline

Definition at line 875 of file map.h.

875 {
876 return ter_set( tripoint( p, abs_sub.z ), new_terrain );
877 }

References abs_sub, ter_set(), and tripoint::z.

◆ ter_set() [2/2]

bool map::ter_set ( const tripoint p,
const ter_id new_terrain 
)

Definition at line 1634 of file map.cpp.

1635{
1636 if( !inbounds( p ) ) {
1637 return false;
1638 }
1639
1640 point l;
1641 submap *const current_submap = get_submap_at( p, l );
1642 const ter_id old_id = current_submap->get_ter( l );
1643 if( old_id == new_terrain ) {
1644 // Nothing changed
1645 return false;
1646 }
1647
1648 current_submap->set_ter( l, new_terrain );
1649
1650 // Set the dirty flags
1651 const ter_t &old_t = old_id.obj();
1652 const ter_t &new_t = new_terrain.obj();
1653
1654 // HACK: Hack around ledges in traplocs or else it gets NASTY in z-level mode
1655 if( old_t.trap != tr_null && old_t.trap != tr_ledge ) {
1656 auto &traps = traplocs[old_t.trap.to_i()];
1657 const auto iter = std::find( traps.begin(), traps.end(), p );
1658 if( iter != traps.end() ) {
1659 traps.erase( iter );
1660 }
1661 }
1662 if( new_t.trap != tr_null && new_t.trap != tr_ledge ) {
1663 traplocs[new_t.trap.to_i()].push_back( p );
1664 }
1665
1666 if( old_t.transparent != new_t.transparent ) {
1669 }
1670
1671 if( old_t.has_flag( TFLAG_INDOORS ) != new_t.has_flag( TFLAG_INDOORS ) ) {
1673 }
1674
1675 if( new_t.has_flag( TFLAG_NO_FLOOR ) != old_t.has_flag( TFLAG_NO_FLOOR ) ) {
1677 // It's a set, not a flag
1678 support_cache_dirty.insert( p );
1680 }
1681
1682 if( new_t.has_flag( TFLAG_SUSPENDED ) != old_t.has_flag( TFLAG_SUSPENDED ) ) {
1684 if( new_t.has_flag( TFLAG_SUSPENDED ) ) {
1685 level_cache &ch = get_cache( p.z );
1686 ch.suspension_cache.emplace_back( getabs( p ).xy() );
1687 }
1688 }
1689
1691
1693
1694 // TODO: Limit to changes that affect move cost, traps and stairs
1696
1697 tripoint above( p.xy(), p.z + 1 );
1698 // Make sure that if we supported something and no longer do so, it falls down
1699 support_dirty( above );
1700
1701 return true;
1702}
std::list< point > suspension_cache
Definition: map.h:302
trap_id trap
Definition: mapdata.h:466

References detail::find(), get_cache(), get_submap_at(), submap::get_ter(), getabs(), map_data_common_t::has_flag(), inbounds(), invalidate_max_populated_zlev(), int_id< T >::obj(), set_floor_cache_dirty(), set_memory_seen_cache_dirty(), set_outside_cache_dirty(), set_pathfinding_cache_dirty(), set_seen_cache_dirty(), set_suspension_cache_dirty(), submap::set_ter(), set_transparency_cache_dirty(), support_cache_dirty, support_dirty(), level_cache::suspension_cache, TFLAG_INDOORS, TFLAG_NO_FLOOR, TFLAG_SUSPENDED, int_id< T >::to_i(), tr_ledge, tr_null, map_data_common_t::transparent, ter_t::trap, traplocs, tripoint::xy(), and tripoint::z.

Referenced by computer_session::action_elevator_on(), computer_session::action_srcf_elevator(), add_computer(), jmapgen_terrain::apply(), jmapgen_computer::apply(), jmapgen_setmap::apply(), apply< ter_t >(), bash_ter_success(), board_up(), MapExtras::burned_ground_parser(), iexamine::cardreader(), iexamine::cardreader_foodplace(), iexamine::cardreader_robofac(), activity_handlers::chop_logs_finish(), activity_handlers::chop_tree_finish(), activity_handlers::churn_finish(), close_door(), collapse_at(), collapse_invalid_suspension(), complete_construction(), iexamine::curtains(), MapExtras::dead_vegetation_parser(), displace_water(), construct::done_deconstruct(), construct::done_digormine_stair(), construct::done_extract_maybe_revert_to_dirt(), construct::done_mine_upstair(), construct::done_ramp_high(), construct::done_ramp_low(), construct::done_wood_stairs(), draw_anthill(), draw_circle_ter(), draw_connections(), draw_lab(), draw_line_ter(), draw_mine(), draw_rough_circle_ter(), draw_slimepit(), draw_square_ter(), draw_temple(), draw_triffid(), avatar_action::eat_here(), explosion_handler::emp_blast(), computer_session::failure_pump_leak(), computer_session::failure_shutdown(), farm_action(), talk_function::field_harvest(), activity_handlers::fill_pit_finish(), dig_activity_actor::finish(), dig_channel_activity_actor::finish(), hacking_activity_actor::finish(), activity_handlers::forage_finish(), game::forced_door_closing(), mapgen_function_json_base::formatted_set_incredibly_simple(), mapf::formatted_set_simple(), fromPumpFuel(), iexamine::fswitch(), activity_handlers::hacksaw_finish(), iexamine::harvest_plant(), iexamine::harvest_ter(), iexamine::harvest_ter_nectar(), hit_with_acid(), talk_function::loot_building(), make_rubble(), mapgen_ants_curved(), mapgen_ants_four_way(), mapgen_ants_generic(), mapgen_ants_straight(), mapgen_ants_tee(), mapgen_cavern(), mapgen_crater(), mapgen_field(), mapgen_forest_trail_curved(), mapgen_forest_trail_four_way(), mapgen_forest_trail_straight(), mapgen_forest_trail_tee(), mapgen_hellmouth(), mapgen_highway(), mapgen_hive(), mapgen_lake_shore(), mapgen_null(), mapgen_parking_lot(), mapgen_rift(), mapgen_river_curved(), mapgen_river_curved_not(), mapgen_river_straight(), mapgen_road(), mapgen_rock_partial(), mapgen_sewer_curved(), mapgen_sewer_four_way(), mapgen_sewer_straight(), mapgen_sewer_tee(), mapgen_tutorial(), fungal_effects::marlossify(), move_vehicle(), MapExtras::mx_bandits_block(), MapExtras::mx_clay_deposit(), MapExtras::mx_clearcut(), MapExtras::mx_grave(), MapExtras::mx_grove(), MapExtras::mx_helicopter(), MapExtras::mx_house_wasp(), MapExtras::mx_pond(), MapExtras::mx_portal_in(), MapExtras::mx_roadblock(), MapExtras::mx_shrubbery(), MapExtras::mx_spider(), om_cutdown_trees(), om_harvest_ter(), om_set_hide_site(), open_door(), gates::open_gate(), activity_handlers::oxytorch_finish(), iexamine::pedestal_temple(), iexamine::pedestal_wyrm(), pick_plant(), iexamine::pit(), iexamine::pit_covered(), MapExtras::place_fumarole(), place_gas_pump(), mission_start::place_npc_software(), process_fields_in_submap(), activity_handlers::pry_nails_finish(), rad_scorch(), mission_start::ranch_nurse_4(), mission_start::ranch_nurse_5(), mission_start::ranch_scavenger_2(), mission_start::ranch_scavenger_3(), resolve_regional_terrain_and_furniture(), restock_fruits(), science_room(), set(), iexamine::shrub_marloss(), fungal_effects::spread_fungus_one_tile(), ter_or_furn_set(), ter_set(), iexamine::toPumpFuel(), ter_furn_transform::transform(), translate(), translate_radius(), iexamine::tree_hickory(), iexamine::tree_maple(), iexamine::tree_maple_tapped(), iexamine::tree_marloss(), turnOnSelectedPump(), and game::vertical_move().

◆ tername() [1/2]

std::string map::tername ( const point p) const
inline

Definition at line 880 of file map.h.

880 {
881 return tername( tripoint( p, abs_sub.z ) );
882 }

References abs_sub, tername(), and tripoint::z.

◆ tername() [2/2]

◆ tinder_at()

bool map::tinder_at ( const tripoint p)

Checks if there are any tinder flagged items on the tile.

Parameters
ptile to check

Definition at line 2610 of file map.cpp.

2611{
2612 for( const auto &i : i_at( p ) ) {
2613 if( i.has_flag( "TINDER" ) ) {
2614 return true;
2615 }
2616 }
2617 return false;
2618}

References i_at().

Referenced by activity_handlers::start_fire_do_turn().

◆ tr_at()

◆ translate()

void map::translate ( const ter_id from,
const ter_id to 
)

Definition at line 3912 of file map.cpp.

3913{
3914 if( from == to ) {
3915 debugmsg( "map::translate %s => %s",
3916 from.obj().name(),
3917 from.obj().name() );
3918 return;
3919 }
3920 for( const tripoint &p : points_on_zlevel() ) {
3921 if( ter( p ) == from ) {
3922 ter_set( p, to );
3923 }
3924 }
3925}

References debugmsg, map_data_common_t::name(), int_id< T >::obj(), points_on_zlevel(), ter(), and ter_set().

Referenced by jmapgen_translate::apply(), mapgen_lake_shore(), start_location::prepare_map(), mission_start::ranch_nurse_5(), mission_start::ranch_nurse_6(), mission_start::ranch_nurse_7(), mission_start::ranch_nurse_8(), and mission_start::ranch_scavenger_3().

◆ translate_radius()

void map::translate_radius ( const ter_id from,
const ter_id to,
float  radi,
const tripoint p,
bool  same_submap = false,
bool  toggle_between = false 
)

Definition at line 3928 of file map.cpp.

3930{
3931 if( from == to ) {
3932 debugmsg( "map::translate %s => %s", from.obj().name(), to.obj().name() );
3933 return;
3934 }
3935
3936 const tripoint abs_omt_p = ms_to_omt_copy( getabs( p ) );
3937 for( const tripoint &t : points_on_zlevel() ) {
3938 const tripoint abs_omt_t = ms_to_omt_copy( getabs( t ) );
3939 const float radiX = trig_dist( p, t );
3940 if( ter( t ) == from ) {
3941 // within distance, and either no submap limitation or same overmap coords.
3942 if( radiX <= radi && ( !same_submap || abs_omt_t == abs_omt_p ) ) {
3943 ter_set( t, to );
3944 }
3945 } else if( toggle_between && ter( t ) == to ) {
3946 if( radiX <= radi && ( !same_submap || abs_omt_t == abs_omt_p ) ) {
3947 ter_set( t, from );
3948 }
3949 }
3950 }
3951}

References debugmsg, getabs(), ms_to_omt_copy(), map_data_common_t::name(), int_id< T >::obj(), points_on_zlevel(), ter(), ter_set(), and trig_dist().

Referenced by computer_session::action_extract_rad_source(), computer_session::action_irradiator(), computer_session::action_lock(), computer_session::action_open(), computer_session::action_release(), computer_session::action_release_bionics(), computer_session::action_shutters(), and computer_session::action_unlock().

◆ trap_locations()

const std::vector< tripoint > & map::trap_locations ( const trap_id type) const

Definition at line 7609 of file map.cpp.

7610{
7611 return traplocs[type.to_i()];
7612}

References traplocs, and type.

◆ trap_set()

void map::trap_set ( const tripoint p,
const trap_id type 
)

Definition at line 5167 of file map.cpp.

5168{
5169 if( !inbounds( p ) ) {
5170 return;
5171 }
5172
5173 point l;
5174 submap *const current_submap = get_submap_at( p, l );
5175 const ter_t &ter = current_submap->get_ter( l ).obj();
5176 if( ter.trap != tr_null ) {
5177 debugmsg( "set trap %s on top of terrain %s which already has a builit-in trap",
5178 type.obj().name(), ter.name() );
5179 return;
5180 }
5181
5182 // If there was already a trap here, remove it.
5183 if( current_submap->get_trap( l ) != tr_null ) {
5184 remove_trap( p );
5185 }
5186
5187 current_submap->set_trap( l, type );
5188 if( type != tr_null ) {
5189 traplocs[type.to_i()].push_back( p );
5190 }
5191}
void remove_trap(const tripoint &p)
Definition: map.cpp:5251

References debugmsg, get_submap_at(), submap::get_ter(), submap::get_trap(), inbounds(), int_id< T >::obj(), remove_trap(), submap::set_trap(), ter(), tr_null, traplocs, and type.

Referenced by jmapgen_trap::apply(), apply< trap >(), construction_activity(), construct::done_mark_firewood(), construct::done_mark_practice_target(), draw_lab(), vehicle::handle_trap(), mtrap_set(), MapExtras::mx_portal(), place_and_add_as_known(), place_construction(), and explosion_handler::explosion_funcs::resonance_cascade().

◆ unboard_vehicle() [1/2]

void map::unboard_vehicle ( const tripoint p,
bool  dead_passenger = false 
)

Definition at line 1096 of file map.cpp.

1097{
1099 player *passenger = nullptr;
1100 if( !vp ) {
1101 debugmsg( "map::unboard_vehicle: vehicle not found" );
1102 // Try and force unboard the player anyway.
1103 passenger = g->critter_at<player>( p );
1104 if( passenger ) {
1105 passenger->in_vehicle = false;
1106 passenger->controlling_vehicle = false;
1107 }
1108 return;
1109 }
1110 passenger = vp->get_passenger();
1111 unboard_vehicle( *vp, passenger, dead_passenger );
1112}
bool controlling_vehicle
Definition: character.h:285

References Character::controlling_vehicle, debugmsg, g, Character::in_vehicle, optional_vpart_position::part_with_feature(), unboard_vehicle(), veh_at(), and VPFLAG_BOARDABLE.

◆ unboard_vehicle() [2/2]

void map::unboard_vehicle ( const vpart_reference vp,
Character passenger,
bool  dead_passenger = false 
)

Definition at line 1076 of file map.cpp.

1077{
1078 // Mark the part as un-occupied regardless of whether there's a live passenger here.
1080 vp.vehicle().invalidate_mass();
1081
1082 if( !passenger ) {
1083 if( !dead_passenger ) {
1084 debugmsg( "map::unboard_vehicle: passenger not found" );
1085 }
1086 return;
1087 }
1088 passenger->in_vehicle = false;
1089 // Only make vehicle go out of control if the driver is the one unboarding.
1090 if( passenger->controlling_vehicle ) {
1091 vp.vehicle().skidding = true;
1092 }
1093 passenger->controlling_vehicle = false;
1094}
void invalidate_mass()
Mark mass caches and pivot cache as dirty.
Definition: vehicle.cpp:6791
vehicle_part & part() const
Yields the vehicle_part object referenced by this.
Definition: vehicle.cpp:6594
::vehicle & vehicle() const

References Character::controlling_vehicle, debugmsg, Character::in_vehicle, vehicle::invalidate_mass(), vpart_reference::part(), vehicle_part::passenger_flag, vehicle_part::remove_flag(), vehicle::skidding, and vpart_reference::vehicle().

Referenced by board_vehicle(), iexamine::chainfence(), detach_vehicle(), game::fling_creature(), talk_function::individual_mission(), game::is_game_over(), npc::move_to(), game::moving_vehicle_dismount(), game::phasing_move(), game::place_player(), game::place_player_overmap(), shake_vehicle(), game::swap_critters(), avatar_action::swim(), unboard_vehicle(), and game::vertical_move().

◆ update_lum()

void map::update_lum ( item_location loc,
bool  add 
)

Update luminosity before and after item's transformation.

Definition at line 4426 of file map.cpp.

4427{
4428 item *target = loc.get_item();
4429
4430 // if the item is not emissive, do nothing
4431 if( !target->is_emissive() ) {
4432 return;
4433 }
4434
4435 point l;
4436 submap *const current_submap = get_submap_at( loc.position(), l );
4437
4438 if( add ) {
4439 current_submap->update_lum_add( l, *target );
4440 } else {
4441 current_submap->update_lum_rem( l, *target );
4442 }
4443}
bool is_emissive() const
Whether the item emits any light at all.
Definition: item.cpp:6782

References om_direction::add(), item_location::get_item(), get_submap_at(), item::is_emissive(), item_location::position(), submap::update_lum_add(), and submap::update_lum_rem().

Referenced by update_lum().

◆ update_pathfinding_cache()

void map::update_pathfinding_cache ( int  zlev) const

Definition at line 8596 of file map.cpp.

8597{
8598 auto &cache = get_pathfinding_cache( zlev );
8599 if( !cache.dirty ) {
8600 return;
8601 }
8602
8603 std::uninitialized_fill_n( &cache.special[0][0], MAPSIZE_X * MAPSIZE_Y, PF_NORMAL );
8604
8605 for( int smx = 0; smx < my_MAPSIZE; ++smx ) {
8606 for( int smy = 0; smy < my_MAPSIZE; ++smy ) {
8607 const auto cur_submap = get_submap_at_grid( { smx, smy, zlev } );
8608 if( !cur_submap ) {
8609 return;
8610 }
8611
8612 tripoint p( 0, 0, zlev );
8613
8614 for( int sx = 0; sx < SEEX; ++sx ) {
8615 p.x = sx + smx * SEEX;
8616 for( int sy = 0; sy < SEEY; ++sy ) {
8617 p.y = sy + smy * SEEY;
8618
8619 pf_special cur_value = PF_NORMAL;
8620
8621 maptile tile( cur_submap, point( sx, sy ) );
8622
8623 const auto &terrain = tile.get_ter_t();
8624 const auto &furniture = tile.get_furn_t();
8625 int part;
8626 const vehicle *veh = veh_at_internal( p, part );
8627
8628 const int cost = move_cost_internal( furniture, terrain, veh, part );
8629
8630 if( cost > 2 ) {
8631 cur_value |= PF_SLOW;
8632 } else if( cost <= 0 ) {
8633 cur_value |= PF_WALL;
8634 if( terrain.has_flag( TFLAG_CLIMBABLE ) ) {
8635 cur_value |= PF_CLIMBABLE;
8636 }
8637 }
8638
8639 if( veh != nullptr ) {
8640 cur_value |= PF_VEHICLE;
8641 }
8642
8643 for( const auto &fld : tile.get_field() ) {
8644 const field_entry &cur = fld.second;
8645 const field_type_id type = cur.get_field_type();
8646 const int field_intensity = cur.get_field_intensity();
8647 if( type.obj().get_dangerous( field_intensity - 1 ) ) {
8648 cur_value |= PF_FIELD;
8649 }
8650 }
8651
8652 if( !tile.get_trap_t().is_benign() || !terrain.trap.obj().is_benign() ) {
8653 cur_value |= PF_TRAP;
8654 }
8655
8656 if( terrain.has_flag( TFLAG_GOES_DOWN ) || terrain.has_flag( TFLAG_GOES_UP ) ||
8657 terrain.has_flag( TFLAG_RAMP ) || terrain.has_flag( TFLAG_RAMP_UP ) ||
8658 terrain.has_flag( TFLAG_RAMP_DOWN ) ) {
8659 cur_value |= PF_UPDOWN;
8660 }
8661
8662 if( terrain.has_flag( TFLAG_SHARP ) ) {
8663 cur_value |= PF_SHARP;
8664 }
8665
8666 cache.special[p.x][p.y] = cur_value;
8667 }
8668 }
8669 }
8670 }
8671
8672 cache.dirty = false;
8673}
@ TFLAG_CLIMBABLE
Definition: mapdata.h:307
@ TFLAG_SHARP
Definition: mapdata.h:296
pf_special
Definition: pathfinding.h:7
@ PF_NORMAL
Definition: pathfinding.h:8
@ PF_FIELD
Definition: pathfinding.h:12

References furniture, maptile::get_field(), field_entry::get_field_intensity(), field_entry::get_field_type(), maptile::get_furn_t(), get_pathfinding_cache(), get_submap_at_grid(), maptile::get_ter_t(), maptile::get_trap_t(), trap::is_benign(), MAPSIZE_X, MAPSIZE_Y, move_cost_internal(), my_MAPSIZE, PF_CLIMBABLE, PF_FIELD, PF_NORMAL, PF_SHARP, PF_SLOW, PF_TRAP, PF_UPDOWN, PF_VEHICLE, PF_WALL, SEEX, SEEY, sx, sy, terrain, TFLAG_CLIMBABLE, TFLAG_GOES_DOWN, TFLAG_GOES_UP, TFLAG_RAMP, TFLAG_RAMP_DOWN, TFLAG_RAMP_UP, TFLAG_SHARP, type, veh_at_internal(), tripoint::x, and tripoint::y.

Referenced by get_pathfinding_cache_ref().

◆ update_submap_active_item_status()

void map::update_submap_active_item_status ( const tripoint p)

Definition at line 5565 of file map.cpp.

5566{
5567 point l;
5568 submap *const current_submap = get_submap_at( p, l );
5569 if( current_submap->active_items.empty() ) {
5570 submaps_with_active_items.erase( tripoint( abs_sub.x + p.x / SEEX, abs_sub.y + p.y / SEEY, p.z ) );
5571 }
5572}

References abs_sub, submap::active_items, active_item_cache::empty(), get_submap_at(), SEEX, SEEY, submaps_with_active_items, tripoint::x, tripoint::y, and tripoint::z.

◆ update_suspension_cache()

void map::update_suspension_cache ( const int &  z)

Definition at line 7915 of file map.cpp.

7916{
7917 level_cache &ch = get_cache( z );
7918 if( !ch.suspension_cache_dirty ) {
7919 return;
7920 }
7921 std::list<point> &suspension_cache = ch.suspension_cache;
7923 for( int smx = 0; smx < my_MAPSIZE; ++smx ) {
7924 for( int smy = 0; smy < my_MAPSIZE; ++smy ) {
7925 const submap *cur_submap = get_submap_at_grid( { smx, smy, z } );
7926
7927 if( cur_submap == nullptr ) {
7928 debugmsg( "Tried to run suspension check at (%d,%d,%d) but the submap is not loaded", smx, smy,
7929 z );
7930 continue;
7931 }
7932
7933 for( int sx = 0; sx < SEEX; ++sx ) {
7934 for( int sy = 0; sy < SEEY; ++sy ) {
7935 point sp( sx, sy );
7936 const ter_t &terrain = cur_submap->get_ter( sp ).obj();
7937 if( terrain.has_flag( TFLAG_SUSPENDED ) ) {
7938 tripoint loc( coords::project_combine( point_om_sm( point( smx, smy ) ), point_sm_ms( sp ) ).raw(),
7939 z );
7940 suspension_cache.emplace_back( getabs( loc ).xy() );
7941 }
7942 }
7943 }
7944 }
7945 }
7947 }
7948
7949 for( auto iter = suspension_cache.begin(); iter != suspension_cache.end(); ) {
7950 const point absp = *iter;
7951 const point locp = getlocal( absp );
7952 const tripoint loctp( locp, z );
7953 if( !inbounds( locp ) ) {
7954 ++iter;
7955 continue;
7956 }
7957 const submap *cur_submap = get_submap_at( loctp );
7958 if( cur_submap == nullptr ) {
7959 debugmsg( "Tried to run suspension check at (%d,%d,%d) but the submap is not loaded", locp.x,
7960 locp.y, z );
7961 ++iter;
7962 continue;
7963 }
7964 const ter_t &terrain = ter( locp ).obj();
7965 if( terrain.has_flag( TFLAG_SUSPENDED ) ) {
7966 if( !is_suspension_valid( loctp ) ) {
7967 support_dirty( loctp );
7968 iter = suspension_cache.erase( iter );
7969 } else {
7970 ++iter;
7971 }
7972 } else {
7973 iter = suspension_cache.erase( iter );
7974 }
7975 }
7976 ch.suspension_cache_dirty = false;
7977}
coords::coord_point< point, coords::origin::overmap, coords::sm > point_om_sm
Definition: coordinates.h:477
auto project_combine(const coord_point< PointL, CoarseOrigin, CoarseScale > &coarse, const coord_point< PointR, FineOrigin, FineScale > &fine)
Definition: coordinates.h:413
bool suspension_cache_initialized
Definition: map.h:300

References debugmsg, get_cache(), get_submap_at(), get_submap_at_grid(), submap::get_ter(), getabs(), getlocal(), inbounds(), is_suspension_valid(), my_MAPSIZE, int_id< T >::obj(), coords::project_combine(), SEEX, SEEY, support_dirty(), level_cache::suspension_cache, level_cache::suspension_cache_dirty, level_cache::suspension_cache_initialized, sx, sy, ter(), terrain, TFLAG_SUSPENDED, point::x, and point::y.

Referenced by build_map_cache().

◆ update_vehicle_cache()

void map::update_vehicle_cache ( vehicle ,
int  old_zlevel 
)

◆ update_vehicle_list()

void map::update_vehicle_list ( const submap to,
int  zlev 
)

Definition at line 336 of file map.cpp.

337{
338 // Update vehicle data
339 level_cache &ch = get_cache( zlev );
340 for( const auto &elem : to->vehicles ) {
341 ch.vehicle_list.insert( elem.get() );
342 if( !elem->loot_zones.empty() ) {
343 ch.zone_vehicles.insert( elem.get() );
344 }
345 }
346
348}

References get_cache(), last_full_vehicle_list_dirty, level_cache::vehicle_list, submap::vehicles, and level_cache::zone_vehicles.

Referenced by displace_vehicle(), editmap::mapgen_preview(), rotate(), shift(), and shift_vehicle_z().

◆ update_visibility_cache()

void map::update_visibility_cache ( int  zlev)

Definition at line 5574 of file map.cpp.

5575{
5576 visibility_variables_cache.variables_set = true; // Not used yet
5577 visibility_variables_cache.g_light_level = static_cast<int>( g->light_level( zlev ) );
5578 visibility_variables_cache.vision_threshold = g->u.get_vision_threshold(
5579 get_cache_ref( g->u.posz() ).lm[g->u.posx()][g->u.posy()].max() );
5580
5581 visibility_variables_cache.u_clairvoyance = g->u.clairvoyance();
5582 visibility_variables_cache.u_sight_impaired = g->u.sight_impaired();
5584
5585 int sm_squares_seen[MAPSIZE][MAPSIZE];
5586 std::memset( sm_squares_seen, 0, sizeof( sm_squares_seen ) );
5587
5588 auto &visibility_cache = get_cache( zlev ).visibility_cache;
5589
5590 tripoint p;
5591 p.z = zlev;
5592 int &x = p.x;
5593 int &y = p.y;
5594 for( x = 0; x < MAPSIZE_X; x++ ) {
5595 for( y = 0; y < MAPSIZE_Y; y++ ) {
5597 visibility_cache[x][y] = ll;
5598 sm_squares_seen[ x / SEEX ][ y / SEEY ] += ( ll == lit_level::BRIGHT || ll == lit_level::LIT );
5599 }
5600 }
5601
5602 for( int gridx = 0; gridx < my_MAPSIZE; gridx++ ) {
5603 for( int gridy = 0; gridy < my_MAPSIZE; gridy++ ) {
5604 if( sm_squares_seen[gridx][gridy] > 36 ) { // 25% of the submap is visible
5605 const tripoint sm( gridx, gridy, 0 );
5606 const auto abs_sm = map::abs_sub + sm;
5607 // TODO: fix point types
5608 const tripoint_abs_omt abs_omt( sm_to_omt_copy( abs_sm ) );
5609 overmap_buffer.set_seen( abs_omt, true );
5610 }
5611 }
5612 }
5613}
lit_level apparent_light_at(const tripoint &p, const visibility_variables &cache) const
Determine the visible light level for a tile, based on light_at for the tile, vision distance,...
Definition: lightmap.cpp:698
void set_seen(const tripoint_abs_omt &p, bool seen=true)
static const efftype_id effect_boomered("boomered")
bool variables_set
Definition: map.h:118
bool u_sight_impaired
Definition: map.h:119

References abs_sub, apparent_light_at(), BRIGHT, effect_boomered, g, visibility_variables::g_light_level, get_cache(), get_cache_ref(), LIT, level_cache::lm, MAPSIZE, MAPSIZE_X, MAPSIZE_Y, four_quadrants::max(), my_MAPSIZE, overmap_buffer, SEEX, SEEY, overmapbuffer::set_seen(), coords::sm, sm_to_omt_copy(), visibility_variables::u_clairvoyance, visibility_variables::u_is_boomered, visibility_variables::u_sight_impaired, visibility_variables::variables_set, level_cache::visibility_cache, visibility_variables_cache, visibility_variables::vision_threshold, tripoint::x, tripoint::y, and tripoint::z.

Referenced by game::draw(), draw(), game::get_player_input(), and game::look_around().

◆ use_amount()

std::list< item > map::use_amount ( const tripoint origin,
int  range,
const itype_id type,
int &  quantity,
const std::function< bool(const item &)> &  filter = return_true<item> 
)

Definition at line 4799 of file map.cpp.

4801{
4802 std::list<item> ret;
4803 for( int radius = 0; radius <= range && quantity > 0; radius++ ) {
4804 for( const tripoint &p : points_in_radius( origin, radius ) ) {
4805 if( rl_dist( origin, p ) >= radius ) {
4806 std::list<item> tmp = use_amount_square( p, type, quantity, filter );
4807 ret.splice( ret.end(), tmp );
4808 }
4809 }
4810 }
4811 return ret;
4812}
std::list< item > use_amount_square(const tripoint &p, const itype_id &type, int &quantity, const std::function< bool(const item &)> &filter=return_true< item >)
Definition: map.cpp:4777

References points_in_radius(), cata::hash64_detail::ret, rl_dist(), type, and use_amount_square().

◆ use_amount_square()

std::list< item > map::use_amount_square ( const tripoint p,
const itype_id type,
int &  quantity,
const std::function< bool(const item &)> &  filter = return_true<item> 
)

Definition at line 4777 of file map.cpp.

4779{
4780 std::list<item> ret;
4781 // Handle infinite map sources.
4782 item water = water_from( p );
4783 if( water.typeId() == type ) {
4784 ret.push_back( water );
4785 quantity = 0;
4786 return ret;
4787 }
4788
4789 if( const cata::optional<vpart_reference> vp = veh_at( p ).part_with_feature( "CARGO", true ) ) {
4790 std::list<item> tmp = use_amount_stack( vp->vehicle().get_items( vp->part_index() ), type,
4791 quantity, filter );
4792 ret.splice( ret.end(), tmp );
4793 }
4794 std::list<item> tmp = use_amount_stack( i_at( p ), type, quantity, filter );
4795 ret.splice( ret.end(), tmp );
4796 return ret;
4797}
item water_from(const tripoint &p)
Definition: map.cpp:4365
std::list< item > use_amount_stack(Stack stack, const itype_id &type, int &quantity, const std::function< bool(const item &)> &filter)
Definition: map.cpp:4763

References i_at(), cata::hash64_detail::ret, type, item::typeId(), use_amount_stack(), veh_at(), and water_from().

Referenced by use_amount().

◆ use_charges()

std::list< item > map::use_charges ( const tripoint origin,
int  range,
const itype_id type,
int &  quantity,
const std::function< bool(const item &)> &  filter = return_true<item>,
basecamp bcp = nullptr 
)

Definition at line 4895 of file map.cpp.

4898{
4899 std::list<item> ret;
4900
4901 // populate a grid of spots that can be reached
4902 std::vector<tripoint> reachable_pts;
4903 reachable_flood_steps( reachable_pts, origin, range, 1, 100 );
4904
4905 // We prefer infinite map sources where available, so search for those
4906 // first
4907 for( const tripoint &p : reachable_pts ) {
4908 // Handle infinite map sources.
4909 item water = water_from( p );
4910 if( water.typeId() == type ) {
4911 water.charges = quantity;
4912 ret.push_back( water );
4913 quantity = 0;
4914 return ret;
4915 }
4916 }
4917
4918 if( bcp ) {
4919 ret = bcp->use_charges( type, quantity );
4920 if( quantity <= 0 ) {
4921 return ret;
4922 }
4923 }
4924
4925 for( const tripoint &p : reachable_pts ) {
4926 if( has_furn( p ) ) {
4927 use_charges_from_furn( furn( p ).obj(), type, quantity, this, p, ret, filter );
4928 if( quantity <= 0 ) {
4929 return ret;
4930 }
4931 }
4932
4933 if( accessible_items( p ) ) {
4934 std::list<item> tmp = use_charges_from_stack( i_at( p ), type, quantity, p, filter );
4935 ret.splice( ret.end(), tmp );
4936 if( quantity <= 0 ) {
4937 return ret;
4938 }
4939 }
4940
4941 const optional_vpart_position vp = veh_at( p );
4942 if( !vp ) {
4943 continue;
4944 }
4945
4946 const cata::optional<vpart_reference> kpart = vp.part_with_feature( "FAUCET", true );
4947 const cata::optional<vpart_reference> weldpart = vp.part_with_feature( "WELDRIG", true );
4948 const cata::optional<vpart_reference> craftpart = vp.part_with_feature( "CRAFTRIG", true );
4949 const cata::optional<vpart_reference> forgepart = vp.part_with_feature( "FORGE", true );
4950 const cata::optional<vpart_reference> kilnpart = vp.part_with_feature( "KILN", true );
4951 const cata::optional<vpart_reference> chempart = vp.part_with_feature( "CHEMLAB", true );
4952 const cata::optional<vpart_reference> autoclavepart = vp.part_with_feature( "AUTOCLAVE", true );
4953 const cata::optional<vpart_reference> cargo = vp.part_with_feature( "CARGO", true );
4954
4955 if( kpart ) { // we have a faucet, now to see what to drain
4956 itype_id ftype = itype_id::NULL_ID();
4957
4958 // Special case hotplates which draw battery power
4959 if( type == itype_hotplate ) {
4960 ftype = itype_battery;
4961 } else {
4962 ftype = type;
4963 }
4964
4965 // TODO: add a sane birthday arg
4967 tmp.charges = kpart->vehicle().drain( ftype, quantity );
4968 // TODO: Handle water poison when crafting starts respecting it
4969 quantity -= tmp.charges;
4970 ret.push_back( tmp );
4971
4972 if( quantity == 0 ) {
4973 return ret;
4974 }
4975 }
4976
4977 if( weldpart ) { // we have a weldrig, now to see what to drain
4978 itype_id ftype = itype_id::NULL_ID();
4979
4980 if( type == itype_welder ) {
4981 ftype = itype_battery;
4982 } else if( type == itype_soldering_iron ) {
4983 ftype = itype_battery;
4984 }
4985 // TODO: add a sane birthday arg
4987 tmp.charges = weldpart->vehicle().drain( ftype, quantity );
4988 quantity -= tmp.charges;
4989 ret.push_back( tmp );
4990
4991 if( quantity == 0 ) {
4992 return ret;
4993 }
4994 }
4995
4996 if( craftpart ) { // we have a craftrig, now to see what to drain
4997 itype_id ftype = itype_id::NULL_ID();
4998
4999 if( type == itype_press ) {
5000 ftype = itype_battery;
5001 } else if( type == itype_vac_sealer ) {
5002 ftype = itype_battery;
5003 } else if( type == itype_dehydrator ) {
5004 ftype = itype_battery;
5005 } else if( type == itype_food_processor ) {
5006 ftype = itype_battery;
5007 }
5008
5009 // TODO: add a sane birthday arg
5011 tmp.charges = craftpart->vehicle().drain( ftype, quantity );
5012 quantity -= tmp.charges;
5013 ret.push_back( tmp );
5014
5015 if( quantity == 0 ) {
5016 return ret;
5017 }
5018 }
5019
5020 if( forgepart ) { // we have a veh_forge, now to see what to drain
5021 itype_id ftype = itype_id::NULL_ID();
5022
5023 if( type == itype_forge ) {
5024 ftype = itype_battery;
5025 }
5026
5027 // TODO: add a sane birthday arg
5029 tmp.charges = forgepart->vehicle().drain( ftype, quantity );
5030 quantity -= tmp.charges;
5031 ret.push_back( tmp );
5032
5033 if( quantity == 0 ) {
5034 return ret;
5035 }
5036 }
5037
5038 if( kilnpart ) { // we have a veh_kiln, now to see what to drain
5039 itype_id ftype = itype_id::NULL_ID();
5040
5041 if( type == itype_kiln ) {
5042 ftype = itype_battery;
5043 }
5044
5045 // TODO: add a sane birthday arg
5047 tmp.charges = kilnpart->vehicle().drain( ftype, quantity );
5048 quantity -= tmp.charges;
5049 ret.push_back( tmp );
5050
5051 if( quantity == 0 ) {
5052 return ret;
5053 }
5054 }
5055
5056 if( chempart ) { // we have a chem_lab, now to see what to drain
5057 itype_id ftype = itype_id::NULL_ID();
5058
5059 if( type == itype_chemistry_set ) {
5060 ftype = itype_battery;
5061 } else if( type == itype_hotplate ) {
5062 ftype = itype_battery;
5063 } else if( type == itype_electrolysis_kit ) {
5064 ftype = itype_battery;
5065 }
5066
5067 // TODO: add a sane birthday arg
5069 tmp.charges = chempart->vehicle().drain( ftype, quantity );
5070 quantity -= tmp.charges;
5071 ret.push_back( tmp );
5072
5073 if( quantity == 0 ) {
5074 return ret;
5075 }
5076 }
5077
5078 if( autoclavepart ) { // we have an autoclave, now to see what to drain
5079 itype_id ftype = itype_id::NULL_ID();
5080
5081 if( type == itype_autoclave ) {
5082 ftype = itype_battery;
5083 }
5084
5085 // TODO: add a sane birthday arg
5087 tmp.charges = autoclavepart->vehicle().drain( ftype, quantity );
5088 quantity -= tmp.charges;
5089 ret.push_back( tmp );
5090
5091 if( quantity == 0 ) {
5092 return ret;
5093 }
5094 }
5095
5096 if( cargo ) {
5097 std::list<item> tmp =
5098 use_charges_from_stack( cargo->vehicle().get_items( cargo->part_index() ), type, quantity, p,
5099 filter );
5100 ret.splice( ret.end(), tmp );
5101 if( quantity <= 0 ) {
5102 return ret;
5103 }
5104 }
5105 }
5106
5107 return ret;
5108}
std::list< item > use_charges(const itype_id &fake_id, int &quantity)
Definition: basecamp.cpp:584
bool accessible_items(const tripoint &t) const
Check whether the player can access the items located .
Definition: map.cpp:6440
void reachable_flood_steps(std::vector< tripoint > &reachable_pts, const tripoint &f, int range, int cost_min, int cost_max) const
Populates a vector of points that are reachable within a number of steps from a point.
Definition: map.cpp:6250
static const itype_id itype_autoclave("autoclave")
static void use_charges_from_furn(const furn_t &f, const itype_id &type, int &quantity, map *m, const tripoint &p, std::list< item > &ret, const std::function< bool(const item &)> &filter)
Definition: map.cpp:4829
static const itype_id itype_soldering_iron("soldering_iron")
static const itype_id itype_chemistry_set("chemistry_set")
std::list< item > use_charges_from_stack(Stack stack, const itype_id &type, int &quantity, const tripoint &pos, const std::function< bool(const item &)> &filter)
Definition: map.cpp:4815
static const itype_id itype_press("press")
static const itype_id itype_hotplate("hotplate")
static const itype_id itype_electrolysis_kit("electrolysis_kit")
static const itype_id itype_food_processor("food_processor")
static const itype_id itype_forge("forge")
static const itype_id itype_battery("battery")
static const itype_id itype_dehydrator("dehydrator")
static const itype_id itype_kiln("kiln")
static const itype_id itype_welder("welder")
static const itype_id itype_vac_sealer("vac_sealer")

References accessible_items(), item::charges, furn(), has_furn(), i_at(), itype_autoclave, itype_battery, itype_chemistry_set, itype_dehydrator, itype_electrolysis_kit, itype_food_processor, itype_forge, itype_hotplate, itype_kiln, itype_press, itype_soldering_iron, itype_vac_sealer, itype_welder, string_id< itype >::NULL_ID(), optional_vpart_position::part_with_feature(), reachable_flood_steps(), cata::hash64_detail::ret, calendar::start_of_cataclysm, type, item::typeId(), basecamp::use_charges(), use_charges_from_furn(), use_charges_from_stack(), veh_at(), and water_from().

Referenced by basecamp_action_components::consume_components(), player::consume_items(), player::consume_tools(), and iexamine::use_furn_fake_item().

◆ valid_move()

bool map::valid_move ( const tripoint from,
const tripoint to,
bool  bash = false,
bool  flying = false,
bool  via_ramp = false 
) const

Returns true if a creature could walk from from to to in one step.

That is, if the tiles are adjacent and either on the same z-level or connected by stairs or (in case of flying monsters) open air with no floors.

Definition at line 1856 of file map.cpp.

1858{
1859 // Used to account for the fact that older versions of GCC can trip on the if statement here.
1860 assert( to.z > std::numeric_limits<int>::min() );
1861 // Note: no need to check inbounds here, because maptile_at will do that
1862 // If oob tile is supplied, the maptile_at will be an unpassable "null" tile
1863 if( std::abs( from.x - to.x ) > 1 || std::abs( from.y - to.y ) > 1 ||
1864 std::abs( from.z - to.z ) > 1 ) {
1865 return false;
1866 }
1867
1868 if( from.z == to.z ) {
1869 // But here we need to, to prevent bashing critters
1870 return passable( to ) || ( bash && inbounds( to ) );
1871 } else if( !zlevels ) {
1872 return false;
1873 }
1874
1875 const bool going_up = from.z < to.z;
1876
1877 const tripoint &up_p = going_up ? to : from;
1878 const tripoint &down_p = going_up ? from : to;
1879
1880 const maptile up = maptile_at( up_p );
1881 const ter_t &up_ter = up.get_ter_t();
1882 if( up_ter.id.is_null() ) {
1883 return false;
1884 }
1885 // Checking for ledge is a workaround for the case when mapgen doesn't
1886 // actually make a valid ledge drop location with zlevels on, this forces
1887 // at least one zlevel drop and if down_ter is impassible it's probably
1888 // inside a wall, we could workaround that further but it's unnecessary.
1889 const bool up_is_ledge = tr_at( up_p ).loadid == tr_ledge;
1890
1891 if( up_ter.movecost == 0 ) {
1892 // Unpassable tile
1893 return false;
1894 }
1895
1896 const maptile down = maptile_at( down_p );
1897 const ter_t &down_ter = down.get_ter_t();
1898 if( down_ter.id.is_null() ) {
1899 return false;
1900 }
1901
1902 if( !up_is_ledge && down_ter.movecost == 0 ) {
1903 // Unpassable tile
1904 return false;
1905 }
1906
1907 if( !up_ter.has_flag( TFLAG_NO_FLOOR ) && !up_ter.has_flag( TFLAG_GOES_DOWN ) && !up_is_ledge &&
1908 !via_ramp ) {
1909 // Can't move from up to down
1910 if( std::abs( from.x - to.x ) == 1 || std::abs( from.y - to.y ) == 1 ) {
1911 // Break the move into two - vertical then horizontal
1912 tripoint midpoint( down_p.xy(), up_p.z );
1913 return valid_move( down_p, midpoint, bash, flying, via_ramp ) &&
1914 valid_move( midpoint, up_p, bash, flying, via_ramp );
1915 }
1916 return false;
1917 }
1918
1919 if( !flying && !down_ter.has_flag( TFLAG_GOES_UP ) && !down_ter.has_flag( TFLAG_RAMP ) &&
1920 !up_is_ledge && !via_ramp ) {
1921 // Can't safely reach the lower tile
1922 return false;
1923 }
1924
1925 if( bash ) {
1926 return true;
1927 }
1928
1929 int part_up;
1930 const vehicle *veh_up = veh_at_internal( up_p, part_up );
1931 if( veh_up != nullptr ) {
1932 // TODO: Hatches below the vehicle, passable frames
1933 return false;
1934 }
1935
1936 int part_down;
1937 const vehicle *veh_down = veh_at_internal( down_p, part_down );
1938 if( veh_down != nullptr && veh_down->roof_at_part( part_down ) >= 0 ) {
1939 // TODO: OPEN (and only open) hatches from above
1940 return false;
1941 }
1942
1943 // Currently only furniture can block movement if everything else is OK
1944 // TODO: Vehicles with boards in the given spot
1945 return up.get_furn_t().movecost >= 0;
1946}
coords::coord_point< Point, Origin, Scale > midpoint(const coords::coord_point< Point, Origin, Scale > &loc1, const coords::coord_point< Point, Origin, Scale > &loc2)
Definition: coordinates.h:562
trap_id loadid
Definition: trap.h:88

References bash(), map_data_common_t::has_flag(), ter_t::id, inbounds(), string_id< T >::is_null(), trap::loadid, maptile_at(), midpoint(), map_data_common_t::movecost, passable(), vehicle::roof_at_part(), TFLAG_GOES_DOWN, TFLAG_GOES_UP, TFLAG_NO_FLOOR, TFLAG_RAMP, tr_at(), tr_ledge, valid_move(), veh_at_internal(), tripoint::x, tripoint::xy(), tripoint::y, tripoint::z, and zlevels.

Referenced by combined_movecost(), explosion_handler::do_blast(), draw_critter_internal(), has_floor_or_support(), scent_map::inbounds(), iexamine::ledge(), monster::move(), process_fields_in_submap(), route(), spread_gas(), monster::stumble(), and valid_move().

◆ veh_at()

optional_vpart_position map::veh_at ( const tripoint p) const

Checks if tile is occupied by vehicle and by which part.

Parameters
pTile to check for vehicle

Definition at line 1004 of file map.cpp.

1005{
1006 if( !inbounds( p ) || !const_cast<map *>( this )->get_cache( p.z ).veh_in_active_range ) {
1008 }
1009
1010 int part_num = 1;
1011 vehicle *const veh = const_cast<map *>( this )->veh_at_internal( p, part_num );
1012 if( !veh ) {
1014 }
1015 return optional_vpart_position( vpart_position( *veh, part_num ) );
1016
1017}
static constexpr nullopt_t nullopt
Definition: optional.h:22

References get_cache(), inbounds(), cata::nullopt, veh_at_internal(), level_cache::veh_in_active_range, and tripoint::z.

Referenced by Character::activate_bionic(), activity_on_turn_move_loot(), zone_manager::add(), add_splatter(), add_vehicle_to_map(), apply_faction_ownership(), are_requirements_nearby(), Creature::auto_find_hostile_target(), Character::base_comfort_value(), bash(), bash_rating(), bash_vehicle(), board_vehicle(), build_seen_cache(), VehicleSpawnFunction::builtin_parkinglot(), Character::burn_fuel(), can_do_activity_there(), can_examine_at(), can_interact_at(), can_pickup_at(), can_put_items(), can_use_bipod(), check_art_charge_req(), vehicle::autodrive_controller::check_drivable(), player::check_eligible_containers_for_crafting(), construct::check_empty(), vehicle::check_heli_ascend(), vehicle::check_heli_descend(), climb_difficulty(), doors::close_door(), veh_interact::complete_vehicle(), game::control_vehicle(), coverage(), creature_in_field(), crush(), debug_menu::debug(), deregister_vehicle_zone(), activity_handlers::repair_activity_hack::anonymous_namespace{activity_handlers.cpp}::discharge_real_power_source(), explosion_handler::do_blast(), game::do_turn(), editmap_hilight::draw(), editmap::draw_main_ui_overlay(), drop_vehicle(), game::examine(), npc::execute_action(), ranged::expected_coverage(), fetch_activity(), activity_handlers::fill_liquid_do_turn(), find_auto_consume(), npc::find_item(), Character::find_remote_fuel(), fire(), game::fling_creature(), Character::floor_bedding_warmth(), Character::floor_item_warmth(), game::forced_door_closing(), inventory::form_from_map(), generic_multi_activity_check_requirement(), avatar::get_book_reader(), game::get_dangerous_tile(), player::get_eligible_containers_for_crafting(), activity_handlers::repair_activity_hack::anonymous_namespace{activity_handlers.cpp}::get_fake_tool(), liquid_handler::get_liquid_target(), overmap_ui::get_overmap_path_to(), game::get_veh_dir_indicator_location(), grab(), game::grabbed_furn_move(), game::grabbed_veh_move(), ranged::gunmode_checks_common(), ranged::gunmode_checks_weapon(), handbrake(), game::handle_action(), handle_action_menu(), Character::has_alarm_clock(), has_nearby_chair(), has_nearby_table(), jmapgen_setmap::has_vehicle_collision(), mapgen_function_json_base::has_vehicle_collision(), jmapgen_alternativly< PieceType >::has_vehicle_collision(), jmapgen_sign::has_vehicle_collision(), jmapgen_vending_machine::has_vehicle_collision(), jmapgen_toilet::has_vehicle_collision(), jmapgen_gaspump::has_vehicle_collision(), jmapgen_vehicle::has_vehicle_collision(), jmapgen_trap::has_vehicle_collision(), jmapgen_furniture::has_vehicle_collision(), jmapgen_terrain::has_vehicle_collision(), jmapgen_computer::has_vehicle_collision(), jmapgen_sealed_item::has_vehicle_collision(), Character::has_watch(), haul(), Character::in_climate_control(), advanced_inv_area::init(), is_bashable(), weather::is_sheltered(), Character::is_snuggling(), game::load(), make_active(), mine_activity(), monster_in_field(), mop_spills(), avatar_action::move(), move_cost(), npc::move_to(), move_vehicle(), game::moving_vehicle_dismount(), MapExtras::mx_helicopter(), obstacle_coverage(), obstacle_name(), open(), open_door(), vehicle::part_collision(), Character::passive_power_gen(), liquid_handler::perform_liquid_transfer(), game::phasing_move(), npc::pick_up_item(), game::place_player(), player_in_field(), pldrive(), game::print_all_tile_info(), projectile_attack(), vehicle_part::properties_to_item(), put_into_vehicle_or_drop(), game::remoteveh(), DefaultRemovePartHandler::removed(), zone_manager::revert_vzones(), iexamine::rubble(), conditional_t< T >::set_is_driving(), set_item_map_or_vehicle(), shoot(), explosion_handler::shrapnel(), iexamine::shrub_wildveggies(), spell_effect::spawn_summoned_vehicle(), autodrive_activity_actor::start(), activity_handlers::start_engines_finish(), supports_above(), game::swap_critters(), avatar_action::swim(), tidy_activity(), unboard_vehicle(), Character::update_bodytemp(), editmap::update_view_with_help(), deploy_furn_actor::use(), deploy_tent_actor::use(), use_amount_square(), use_charges(), game::validate_linked_vehicles(), vehicle_activity(), activity_handlers::vehicle_finish(), vehicle_selector::vehicle_selector(), wait(), game::walk_move(), game::wield(), and workbench_crafting_speed_multiplier().

◆ veh_at_internal() [1/2]

vehicle * map::veh_at_internal ( const tripoint p,
int &  part_num 
)

Definition at line 1039 of file map.cpp.

1040{
1041 return const_cast<vehicle *>( const_cast<const map *>( this )->veh_at_internal( p, part_num ) );
1042}

References veh_at_internal().

Referenced by draw_from_above(), draw_maptile(), process_fields_in_submap(), route(), update_pathfinding_cache(), valid_move(), veh_at(), and veh_at_internal().

◆ veh_at_internal() [2/2]

const vehicle * map::veh_at_internal ( const tripoint p,
int &  part_num 
) const

Definition at line 1019 of file map.cpp.

1020{
1021 // This function is called A LOT. Move as much out of here as possible.
1022 const level_cache &ch = get_cache( p.z );
1023 if( !ch.veh_in_active_range || !ch.veh_exists_at[p.x][p.y] ) {
1024 part_num = -1;
1025 return nullptr; // Clear cache indicates no vehicle. This should optimize a great deal.
1026 }
1027
1028 const auto it = ch.veh_cached_parts.find( p );
1029 if( it != ch.veh_cached_parts.end() ) {
1030 part_num = it->second.second;
1031 return it->second.first;
1032 }
1033
1034 debugmsg( "vehicle part cache indicated vehicle not found: %d %d %d", p.x, p.y, p.z );
1035 part_num = -1;
1036 return nullptr;
1037}

References debugmsg, get_cache(), level_cache::veh_cached_parts, level_cache::veh_exists_at, level_cache::veh_in_active_range, tripoint::x, tripoint::y, and tripoint::z.

◆ vehicle_vehicle_collision()

float map::vehicle_vehicle_collision ( vehicle veh,
vehicle veh2,
const std::vector< veh_collision > &  collisions 
)

Definition at line 757 of file map.cpp.

759{
760 if( &veh == &veh2 ) {
761 debugmsg( "Vehicle %s collided with itself", veh.name );
762 return 0.0f;
763 }
764
765 // Effects of colliding with another vehicle:
766 // transfers of momentum, skidding,
767 // parts are damaged/broken on both sides,
768 // remaining times are normalized
769 const veh_collision &c = collisions[0];
770 add_msg( m_bad, _( "The %1$s's %2$s collides with %3$s's %4$s." ),
771 veh.name, veh.part_info( c.part ).name(),
772 veh2.name, veh2.part_info( c.target_part ).name() );
773
774 const bool vertical = veh.sm_pos.z != veh2.sm_pos.z;
775
776 // Used to calculate the epicenter of the collision.
777 point epicenter1;
778 point epicenter2;
779
780 float dmg;
781 // Vertical collisions will be simpler for a while (1D)
782 if( !vertical ) {
783 // For reference, a cargo truck weighs ~25300, a bicycle 690,
784 // and 38mph is 3800 'velocity'
785 rl_vec2d velo_veh1 = veh.velo_vec();
786 rl_vec2d velo_veh2 = veh2.velo_vec();
787 const float m1 = to_kilogram( veh.total_mass() );
788 const float m2 = to_kilogram( veh2.total_mass() );
789 //Energy of vehicle1 and vehicle2 before collision
790 float E = 0.5 * m1 * velo_veh1.magnitude() * velo_veh1.magnitude() +
791 0.5 * m2 * velo_veh2.magnitude() * velo_veh2.magnitude();
792
793 // Collision_axis
794 point cof1 = veh .rotated_center_of_mass();
795 point cof2 = veh2.rotated_center_of_mass();
796 int &x_cof1 = cof1.x;
797 int &y_cof1 = cof1.y;
798 int &x_cof2 = cof2.x;
799 int &y_cof2 = cof2.y;
800 rl_vec2d collision_axis_y;
801
802 collision_axis_y.x = ( veh.global_pos3().x + x_cof1 ) - ( veh2.global_pos3().x + x_cof2 );
803 collision_axis_y.y = ( veh.global_pos3().y + y_cof1 ) - ( veh2.global_pos3().y + y_cof2 );
804 collision_axis_y = collision_axis_y.normalized();
805 rl_vec2d collision_axis_x = collision_axis_y.rotated( M_PI / 2 );
806 // imp? & delta? & final? reworked:
807 // newvel1 =( vel1 * ( mass1 - mass2 ) + ( 2 * mass2 * vel2 ) ) / ( mass1 + mass2 )
808 // as per http://en.wikipedia.org/wiki/Elastic_collision
809 //velocity of veh1 before collision in the direction of collision_axis_y
810 float vel1_y = collision_axis_y.dot_product( velo_veh1 );
811 float vel1_x = collision_axis_x.dot_product( velo_veh1 );
812 //velocity of veh2 before collision in the direction of collision_axis_y
813 float vel2_y = collision_axis_y.dot_product( velo_veh2 );
814 float vel2_x = collision_axis_x.dot_product( velo_veh2 );
815 // e = 0 -> inelastic collision
816 // e = 1 -> elastic collision
817 float e = get_collision_factor( vel1_y / 100 - vel2_y / 100 );
818
819 // Velocity after collision
820 // vel1_x_a = vel1_x, because in x-direction we have no transmission of force
821 float vel1_x_a = vel1_x;
822 float vel2_x_a = vel2_x;
823 // Transmission of force only in direction of collision_axix_y
824 // Equation: partially elastic collision
825 float vel1_y_a = ( m2 * vel2_y * ( 1 + e ) + vel1_y * ( m1 - m2 * e ) ) / ( m1 + m2 );
826 float vel2_y_a = ( m1 * vel1_y * ( 1 + e ) + vel2_y * ( m2 - m1 * e ) ) / ( m1 + m2 );
827 // Add both components; Note: collision_axis is normalized
828 rl_vec2d final1 = collision_axis_y * vel1_y_a + collision_axis_x * vel1_x_a;
829 rl_vec2d final2 = collision_axis_y * vel2_y_a + collision_axis_x * vel2_x_a;
830
831 veh.move.init( final1.as_point() );
832 if( final1.dot_product( veh.face_vec() ) < 0 ) {
833 // Car is being pushed backwards. Make it move backwards
834 veh.velocity = -final1.magnitude();
835 } else {
836 veh.velocity = final1.magnitude();
837 }
838
839 veh2.move.init( final2.as_point() );
840 if( final2.dot_product( veh2.face_vec() ) < 0 ) {
841 // Car is being pushed backwards. Make it move backwards
842 veh2.velocity = -final2.magnitude();
843 } else {
844 veh2.velocity = final2.magnitude();
845 }
846
847 //give veh2 the initiative to proceed next before veh1
848 float avg_of_turn = ( veh2.of_turn + veh.of_turn ) / 2;
849 if( avg_of_turn < .1f ) {
850 avg_of_turn = .1f;
851 }
852
853 veh.of_turn = avg_of_turn * .9;
854 veh2.of_turn = avg_of_turn * 1.1;
855
856 //Energy after collision
857 float E_a = 0.5 * m1 * final1.magnitude() * final1.magnitude() +
858 0.5 * m2 * final2.magnitude() * final2.magnitude();
859 float d_E = E - E_a; //Lost energy at collision -> deformation energy
860 dmg = std::abs( d_E / 1000 / 2000 ); //adjust to balance damage
861 } else {
862 const float m1 = to_kilogram( veh.total_mass() );
863 // Collision is perfectly inelastic for simplicity
864 // Assume veh2 is standing still
865 dmg = std::abs( veh.vertical_velocity / 100 ) * m1 / 10;
866 veh.vertical_velocity = 0;
867 }
868
869 float dmg_veh1 = dmg * 0.5;
870 float dmg_veh2 = dmg * 0.5;
871
872 int coll_parts_cnt = 0; //quantity of colliding parts between veh1 and veh2
873 for( const auto &veh_veh_coll : collisions ) {
874 if( &veh2 == static_cast<vehicle *>( veh_veh_coll.target ) ) {
875 coll_parts_cnt++;
876 }
877 }
878
879 const float dmg1_part = dmg_veh1 / coll_parts_cnt;
880 const float dmg2_part = dmg_veh2 / coll_parts_cnt;
881
882 //damage colliding parts (only veh1 and veh2 parts)
883 for( const auto &veh_veh_coll : collisions ) {
884 if( &veh2 != static_cast<vehicle *>( veh_veh_coll.target ) ) {
885 continue;
886 }
887
888 int parm1 = veh.part_with_feature( veh_veh_coll.part, VPFLAG_ARMOR, true );
889 if( parm1 < 0 ) {
890 parm1 = veh_veh_coll.part;
891 }
892 int parm2 = veh2.part_with_feature( veh_veh_coll.target_part, VPFLAG_ARMOR, true );
893 if( parm2 < 0 ) {
894 parm2 = veh_veh_coll.target_part;
895 }
896
897 epicenter1 += veh.part( parm1 ).mount;
898 veh.damage( parm1, dmg1_part, DT_BASH );
899
900 epicenter2 += veh2.part( parm2 ).mount;
901 veh2.damage( parm2, dmg2_part, DT_BASH );
902 }
903
904 epicenter2.x /= coll_parts_cnt;
905 epicenter2.y /= coll_parts_cnt;
906
907 if( dmg2_part > 100 ) {
908 // Shake vehicle because of collision
909 veh2.damage_all( dmg2_part / 2, dmg2_part, DT_BASH, epicenter2 );
910 }
911
912 if( dmg_veh1 > 800 ) {
913 veh.skidding = true;
914 }
915
916 if( dmg_veh2 > 800 ) {
917 veh2.skidding = true;
918 }
919
920 // Return the impulse of the collision
921 return dmg_veh1;
922}
rl_vec2d face_vec() const
const point & rotated_center_of_mass() const
Definition: vehicle.cpp:3150
rl_vec2d velo_vec() const
float of_turn
Definition: vehicle.h:1911
std::string name() const
Translated name of a part.
Definition: veh_type.cpp:699
#define M_PI
Definition: math_defines.h:21
point as_point() const
Definition: line.cpp:686
rl_vec2d rotated(float angle) const
Definition: line.cpp:647
float magnitude() const
Definition: line.cpp:610
rl_vec2d normalized() const
Definition: line.cpp:620
float y
Definition: point_float.h:13
float x
Definition: point_float.h:12
float dot_product(const rl_vec2d &v) const
Definition: line.cpp:664
@ VPFLAG_ARMOR
Definition: veh_type.h:32
float get_collision_factor(float delta_v)

References _, add_msg(), rl_vec2d::as_point(), c, vehicle::damage(), vehicle::damage_all(), debugmsg, rl_vec2d::dot_product(), DT_BASH, vehicle::face_vec(), get_collision_factor(), vehicle::global_pos3(), tileray::init(), m_bad, M_PI, rl_vec2d::magnitude(), vehicle_part::mount, vehicle::move, vpart_info::name(), vehicle::name, rl_vec2d::normalized(), vehicle::of_turn, vehicle::part(), vehicle::part_info(), vehicle::part_with_feature(), rl_vec2d::rotated(), vehicle::rotated_center_of_mass(), vehicle::skidding, vehicle::sm_pos, units::to_kilogram(), vehicle::total_mass(), vehicle::velo_vec(), vehicle::velocity, vehicle::vertical_velocity, VPFLAG_ARMOR, point::x, tripoint::x, rl_vec2d::x, point::y, tripoint::y, rl_vec2d::y, and tripoint::z.

Referenced by move_vehicle().

◆ vehicle_wheel_traction()

float map::vehicle_wheel_traction ( const vehicle veh,
bool  ignore_movement_modifiers = false 
) const

Definition at line 1567 of file vehicle_move.cpp.

1569{
1570 if( veh.is_in_water( true ) ) {
1571 return veh.can_float() ? 1.0f : -1.0f;
1572 }
1573 if( veh.is_in_water() && veh.is_watercraft() && veh.can_float() ) {
1574 return 1.0f;
1575 }
1576
1577 const auto &wheel_indices = veh.wheelcache;
1578 int num_wheels = wheel_indices.size();
1579 if( num_wheels == 0 ) {
1580 // TODO: Assume it is digging in dirt
1581 // TODO: Return something that could be reused for dragging
1582 return 0.0f;
1583 }
1584
1585 float traction_wheel_area = 0.0f;
1586
1587 if( vehicle_movement::is_on_rails( *this, veh ) ) {
1588 // Vehicles on rails are considered to have all of their wheels on rails
1589 for( int p : veh.rail_wheelcache ) {
1590 traction_wheel_area += veh.cpart( p ).wheel_area();
1591 }
1592 return traction_wheel_area;
1593 }
1594
1595 for( int p : wheel_indices ) {
1596 const tripoint &pp = veh.global_part_pos3( p );
1597 const int wheel_area = veh.cpart( p ).wheel_area();
1598
1599 const auto &tr = ter( pp ).obj();
1600 // Deep water and air
1601 if( tr.has_flag( TFLAG_DEEP_WATER ) || tr.has_flag( TFLAG_NO_FLOOR ) ) {
1602 // No traction from wheel in water or air
1603 continue;
1604 }
1605
1606 int move_mod = move_cost_ter_furn( pp );
1607 if( move_mod == 0 ) {
1608 // Vehicle locked in wall
1609 // Shouldn't happen, but does
1610 return 0.0f;
1611 }
1612
1613 for( const auto &terrain_mod : veh.part_info( p ).wheel_terrain_mod() ) {
1614 if( !tr.has_flag( terrain_mod.first ) ) {
1615 move_mod += terrain_mod.second;
1616 break;
1617 }
1618 }
1619
1620 // Ignore the movement modifier if needed.
1621 if( ignore_movement_modifiers ) {
1622 move_mod = 2;
1623 }
1624
1625 traction_wheel_area += 2.0 * wheel_area / move_mod;
1626 }
1627
1628 return traction_wheel_area;
1629}
bool is_watercraft() const
Definition: vehicle.cpp:4040
std::vector< int > rail_wheelcache
Definition: vehicle.h:1800
bool can_float() const
can_float does the vehicle have freeboard or does it overflow with water?
Definition: vehicle.cpp:3977
std::vector< std::pair< std::string, int > > wheel_terrain_mod() const
Definition: veh_type.cpp:897
bool is_on_rails(const map &m, const vehicle &veh)
Returns whether the vehicle is currently on rails.

References vehicle::can_float(), vehicle::cpart(), vehicle::global_part_pos3(), vehicle::is_in_water(), vehicle_movement::is_on_rails(), vehicle::is_watercraft(), move_cost_ter_furn(), int_id< T >::obj(), vehicle::part_info(), vehicle::rail_wheelcache, ter(), TFLAG_DEEP_WATER, TFLAG_NO_FLOOR, vehicle_part::wheel_area(), vpart_info::wheel_terrain_mod(), and vehicle::wheelcache.

Referenced by vehicle::act_on_map(), and move_vehicle().

◆ vehmove()

void map::vehmove ( )

Definition at line 410 of file map.cpp.

411{
412 // give vehicles movement points
413 VehicleList vehicle_list;
414 int minz = zlevels ? -OVERMAP_DEPTH : abs_sub.z;
415 int maxz = zlevels ? OVERMAP_HEIGHT : abs_sub.z;
416 for( int zlev = minz; zlev <= maxz; ++zlev ) {
417 level_cache &cache = get_cache( zlev );
418 for( vehicle *veh : cache.vehicle_list ) {
419 veh->gain_moves();
420 veh->slow_leak();
422 w.v = veh;
423 vehicle_list.push_back( w );
424 }
425 }
426
427 // 15 equals 3 >50mph vehicles, or up to 15 slow (1 square move) ones
428 // But 15 is too low for V12 death-bikes, let's put 100 here
429 for( int count = 0; count < 100; count++ ) {
430 if( !vehproceed( vehicle_list ) ) {
431 break;
432 }
433 }
434 // Process item removal on the vehicles that were modified this turn.
435 // Use a copy because part_removal_cleanup can modify the container.
436 auto temp = dirty_vehicle_list;
437 for( const auto &elem : temp ) {
438 auto same_ptr = [ elem ]( const struct wrapped_vehicle & tgt ) {
439 return elem == tgt.v;
440 };
441 if( std::find_if( vehicle_list.begin(), vehicle_list.end(), same_ptr ) !=
442 vehicle_list.end() ) {
443 elem->part_removal_cleanup();
444 }
445 }
446 dirty_vehicle_list.clear();
447 // The bool tracks whether the vehicles is on the map or not.
448 std::map<vehicle *, bool> connected_vehicles;
449 for( int zlev = minz; zlev <= maxz; ++zlev ) {
450 level_cache &cache = get_cache( zlev );
451 vehicle::enumerate_vehicles( connected_vehicles, cache.vehicle_list );
452 }
453 for( std::pair<vehicle *const, bool> &veh_pair : connected_vehicles ) {
454 veh_pair.first->idle( veh_pair.second );
455 }
456}
bool vehproceed(VehicleList &vehicle_list)
Definition: map.cpp:458
static void enumerate_vehicles(std::map< vehicle *, bool > &connected_vehicles, const std::set< vehicle * > &vehicle_list)
Use grid traversal to enumerate all connected vehicles.
Definition: vehicle.cpp:4750
void slow_leak()
Definition: vehicle.cpp:5117
void gain_moves()
Definition: vehicle.cpp:5364

References abs_sub, detail::count(), dirty_vehicle_list, vehicle::enumerate_vehicles(), vehicle::gain_moves(), get_cache(), OVERMAP_DEPTH, OVERMAP_HEIGHT, vehicle::slow_leak(), wrapped_vehicle::v, level_cache::vehicle_list, vehproceed(), tripoint::z, and zlevels.

Referenced by game::do_turn().

◆ vehproceed()

bool map::vehproceed ( VehicleList vehicle_list)

Definition at line 458 of file map.cpp.

459{
460 wrapped_vehicle *cur_veh = nullptr;
461 float max_of_turn = 0;
462 // First horizontal movement
463 for( wrapped_vehicle &vehs_v : vehicle_list ) {
464 if( vehs_v.v->of_turn > max_of_turn ) {
465 cur_veh = &vehs_v;
466 max_of_turn = cur_veh->v->of_turn;
467 }
468 }
469
470 // Then vertical-only movement
471 if( cur_veh == nullptr ) {
472 for( wrapped_vehicle &vehs_v : vehicle_list ) {
473 if( vehs_v.v->is_falling || ( vehs_v.v->is_rotorcraft() && vehs_v.v->get_z_change() != 0 ) ) {
474 cur_veh = &vehs_v;
475 break;
476 }
477 }
478 }
479
480 if( cur_veh == nullptr ) {
481 return false;
482 }
483
484 cur_veh->v = cur_veh->v->act_on_map();
485 if( cur_veh->v == nullptr ) {
486 vehicle_list = get_vehicles();
487 }
488
489 // confirm that veh_in_active_range is still correct for each z-level
490 int minz = zlevels ? -OVERMAP_DEPTH : abs_sub.z;
491 int maxz = zlevels ? OVERMAP_HEIGHT : abs_sub.z;
492 for( int zlev = minz; zlev <= maxz; ++zlev ) {
493 level_cache &cache = get_cache( zlev );
494
495 // Check if any vehicles exist in the active range for this z-level
497 std::any_of( std::begin( cache.veh_exists_at ),
498 std::end( cache.veh_exists_at ), []( const auto & row ) {
499 return std::any_of( std::begin( row ), std::end( row ), []( bool veh_exists ) {
500 return veh_exists;
501 } );
502 } );
503 }
504
505 return true;
506}
vehicle * act_on_map()

References abs_sub, vehicle::act_on_map(), get_cache(), get_vehicles(), vehicle::of_turn, OVERMAP_DEPTH, OVERMAP_HEIGHT, wrapped_vehicle::v, level_cache::veh_exists_at, level_cache::veh_in_active_range, tripoint::z, and zlevels.

Referenced by vehmove().

◆ vertical_shift()

void map::vertical_shift ( int  newz)

Moves the map vertically to (not by!) newz.

Does not actually shift anything, only forces cache updates. In the future, it will either actually shift the map or it will get removed after 3D migration is complete.

Definition at line 6767 of file map.cpp.

6768{
6769 if( !zlevels ) {
6770 debugmsg( "Called map::vertical_shift in a non-z-level world" );
6771 return;
6772 }
6773
6774 if( newz < -OVERMAP_DEPTH || newz > OVERMAP_HEIGHT ) {
6775 debugmsg( "Tried to get z-level %d outside allowed range of %d-%d",
6776 newz, -OVERMAP_DEPTH, OVERMAP_HEIGHT );
6777 return;
6778 }
6779
6780 tripoint trp = get_abs_sub();
6781 set_abs_sub( tripoint( trp.xy(), newz ) );
6782
6783 // TODO: Remove the function when it's safe
6784 return;
6785}

References debugmsg, get_abs_sub(), OVERMAP_DEPTH, OVERMAP_HEIGHT, set_abs_sub(), tripoint::xy(), and zlevels.

Referenced by game::vertical_shift().

◆ water_from()

item map::water_from ( const tripoint p)

Definition at line 4365 of file map.cpp.

4366{
4367 if( has_flag( "SALT_WATER", p ) ) {
4369 }
4370
4371 const ter_id terrain_id = ter( p );
4372 if( terrain_id == t_sewage ) {
4374 ret.poison = rng( 1, 7 );
4375 return ret;
4376 }
4377
4379 // iexamine::water_source requires a valid liquid from this function.
4380 if( terrain_id.obj().examine == &iexamine::water_source ) {
4381 int poison_chance = 0;
4382 if( terrain_id.obj().has_flag( TFLAG_DEEP_WATER ) ) {
4383 if( terrain_id.obj().has_flag( TFLAG_CURRENT ) ) {
4384 poison_chance = 20;
4385 } else {
4386 poison_chance = 4;
4387 }
4388 } else {
4389 if( terrain_id.obj().has_flag( TFLAG_CURRENT ) ) {
4390 poison_chance = 10;
4391 } else {
4392 poison_chance = 3;
4393 }
4394 }
4395 if( one_in( poison_chance ) ) {
4396 ret.poison = rng( 1, 4 );
4397 }
4398 return ret;
4399 }
4400 if( furn( p ).obj().examine == &iexamine::water_source ) {
4401 return ret;
4402 }
4403 return item();
4404}
static const int INFINITE_CHARGES
Definition: item.h:2154
void examine(Character &p, const tripoint &pos)
Calls the examine function of furniture or terrain at given tile, for given character.
Definition: map.cpp:1615
@ TFLAG_CURRENT
Definition: mapdata.h:302
void water_source(player &p, const tripoint &examp)
Definition: iexamine.cpp:3793

References examine(), map_data_common_t::examine, furn(), map_data_common_t::has_flag(), has_flag(), item::INFINITE_CHARGES, int_id< T >::obj(), one_in(), cata::hash64_detail::ret, rng(), calendar::start_of_cataclysm, t_sewage, ter(), TFLAG_CURRENT, TFLAG_DEEP_WATER, and iexamine::water_source().

Referenced by inventory::form_from_map(), use_amount_square(), use_charges(), and iexamine::water_source().

Friends And Related Function Documentation

◆ editmap

friend class editmap
friend

Definition at line 373 of file map.h.

◆ visitable< map_cursor >

friend class visitable< map_cursor >
friend

Definition at line 373 of file map.h.

Member Data Documentation

◆ abs_sub

tripoint map::abs_sub
protected

Absolute coordinates of first submap (get_submap_at(0,0)) This is in submap coordinates (see overmapbuffer for explanation).

It is set upon:

  • loading submap at grid[0],
  • generating submaps (generate)
  • shifting the map with shift

Definition at line 1805 of file map.h.

Referenced by add_item(), add_item_or_charges(), add_vehicle(), adjust_radiation(), apply_faction_ownership(), bash_rating(), bash_resistance(), bash_strength(), build_floor_caches(), can_put_items(), can_put_items_ter_furn(), check_submap_active_item_consistency(), clear_vehicle_cache(), create_anomaly(), decay_fields_and_scent(), detach_vehicle(), draw_fill_background(), draw_lab(), draw_mine(), draw_temple(), draw_triffid(), features(), furn(), furn_set(), furnname(), generate(), get_abs_sub(), get_active_items_in_radius(), get_nonant(), get_submap_at(), get_vehicles(), getabs(), getlocal(), has_flag(), has_flag_furn(), has_flag_ter(), has_flag_ter_or_furn(), has_furn(), i_at(), i_clear(), i_rem(), is_bashable(), is_bashable_furn(), is_bashable_ter(), is_bashable_ter_furn(), is_divable(), is_outside(), is_water_shallow_current(), loadn(), make_active(), move_cost(), move_cost_ter_furn(), name(), passable(), place_items(), place_npc(), place_vending(), points_on_zlevel(), process_fields(), process_fields_in_submap(), process_items(), reset_vehicle_cache(), rotate(), save(), saven(), scent_blockers(), set_abs_sub(), set_radiation(), set_temperature(), spawn_an_item(), spawn_item(), spawn_items(), spawn_monsters(), spawn_monsters_submap(), spawn_monsters_submap_group(), ter(), ter_set(), tername(), update_submap_active_item_status(), update_visibility_cache(), vehmove(), and vehproceed().

◆ caches

std::array< std::unique_ptr<level_cache>, OVERMAP_LAYERS > map::caches
private

Holds caches for visibility, light, transparency and vehicles.

Definition at line 1977 of file map.h.

Referenced by access_cache(), get_cache(), get_cache_ref(), and map().

◆ dirty_vehicle_list

◆ field_furn_locs

std::vector<tripoint> map::field_furn_locs
private

Vector of tripoints containing active field-emitting furniture.

Definition at line 1973 of file map.h.

Referenced by actualize(), furn_set(), get_furn_field_locations(), load(), and shift_traps().

◆ grid

std::vector<submap *> map::grid
private

The list of currently loaded submaps.

The size of this should not be changed. After calling load or generate, it should only contain non-null pointers. Use getsubmap or setsubmap to access it.

Definition at line 1962 of file map.h.

Referenced by actualize(), add_roofs(), clear_spawns(), clear_traps(), editmap::cleartmpmap(), displace_vehicle(), getsubmap(), loadn(), map(), saven(), and setsubmap().

◆ last_full_vehicle_list

VehicleList map::last_full_vehicle_list
private

Vehicle list doesn't change often, but is pretty expensive.

Definition at line 1993 of file map.h.

Referenced by get_vehicles().

◆ last_full_vehicle_list_dirty

bool map::last_full_vehicle_list_dirty = true
private

◆ max_populated_zlev

cata::optional<std::pair<tripoint, int> > map::max_populated_zlev = cata::nullopt
private

Definition at line 2007 of file map.h.

Referenced by calc_max_populated_zlev(), and invalidate_max_populated_zlev().

◆ my_MAPSIZE

◆ pathfinding_caches

std::array< std::unique_ptr<pathfinding_cache>, OVERMAP_LAYERS > map::pathfinding_caches
mutableprivate

Definition at line 1979 of file map.h.

Referenced by get_pathfinding_cache(), get_pathfinding_cache_ref(), and map().

◆ skew_vision_cache

lru_cache<point, char> map::skew_vision_cache
mutableprivate

Cache of coordinate pairs recently checked for visibility.

Definition at line 1988 of file map.h.

Referenced by build_map_cache(), and sees().

◆ submaps_with_active_items

std::set<tripoint> map::submaps_with_active_items
private

◆ support_cache_dirty

std::set<tripoint> map::support_cache_dirty
private

Definition at line 1523 of file map.h.

Referenced by process_falling(), shift(), support_dirty(), and ter_set().

◆ traplocs

std::vector< std::vector<tripoint> > map::traplocs
private

This vector contains an entry for each trap type, it has therefor the same size as the traplist vector.

Each entry contains a list of all point on the map that contain a trap of that type. The first entry however is always empty as it denotes the tr_null trap.

Definition at line 1969 of file map.h.

Referenced by actualize(), clear_traps(), load(), map(), remove_trap(), shift_traps(), ter_set(), trap_locations(), and trap_set().

◆ visibility_variables_cache

visibility_variables map::visibility_variables_cache
private

Definition at line 2003 of file map.h.

Referenced by get_visibility_variables_cache(), and update_visibility_cache().

◆ zlevels


The documentation for this class was generated from the following files: